gRPC requests under the hood are served using a cachedThreadPool.. based on this SO post, it seems like we should always provide our own executor.
This actually becomes important as clients who consume our SDK might want control over the thread pool management, especially if they're interacting with multiple subsystems. At the very least, I believe we should expose this for advanced users if they want to configure their own thread pool.