I have a gRPC server, written in Python 3.6. This server follows the pattern described in the gRPC examples as follows:
from concurrent import futures
import logging
import grpc
import helloworld_pb2
import helloworld_pb2_grpc
class Greeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
# ...
def ReadRemoteData(self, request, context):
return fetch_some_data_io_bound()
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
server.add_insecure_port('[::]:50051')
server.start()
server.wait_for_termination()
if __name__ == '__main__':
logging.basicConfig()
serve()
In my server application, there are a lot more methods, but in general is more of the same.
There are a number of these methods that are currently a bottleneck for my server and I would like to optimize those by running them using async
(these methods spend good time waiting on IO so they are a good candidate).
The newest versions of grpc
now support async
as seen in this example, by creating an async server with server = grpc.aio.server()
.
My problem is the following:
The server has a lot of gRPC methods, many of which are very complex. I would like to avoid rewriting any method that is not currently a bottleneck and leave them as they are. I would like to rewrite only those methods that would benefit from an async implementation, which is just a small fraction of the total. I can't change the .proto
definition to split the service into async/non-async, for backwards-compatibility reasons.
The question is, is it possible to combine, somehow, async and non async methods in the same gRPC service?