Can Python gRPC do computation when sending messages out?

415 Views Asked by At

Suppose I need to send a large amount of data from the client to the server using python gRPC. And I want to continue the rest computation when sending the message out instead of blocking the code. Is there any way can implement this?

I will illustrate the question by an example using the modified code from the greeter_client.py

  for i in range(5):
      res=computation()
      response = stub.SayHello(helloworld_pb2.HelloRequest(data=res))

I want the computation of the next iteration continue while sending the "res" of last iteration. To this end, I have tried the "async/await", which looks like this

async with aio.insecure_channel('localhost:50051') as channel:
    stub = helloworld_pb2_grpc.GreeterStub(channel)
    for j in range(5):
        res=computation()
        response = await stub.SayHello(helloworld_pb2.HelloRequest(data=res))

But the running time is actually the same with the version without async/await. The async/await does not work. I am wondering is there anything wrong in my codes or there are other ways?

1

There are 1 best solutions below

0
On

Concurrency is different than parallelism. AsyncIO allows multiple coroutines to run on the same thread, but they are not actually computed at the same time. If the thread is given a CPU-heavy work like "computation()" in your snippet, it doesn't yield control back to the event loop, hence there won't be any progress on other coroutines.

Besides, in the snippet, the RPC depends on the result of "computation()", this meant the work will be serialized for each RPC. But we can still gain some concurrency from AsyncIO, by handing them over to the event loop with asyncio.gather():

async with aio.insecure_channel('localhost:50051') as channel:
    stub = helloworld_pb2_grpc.GreeterStub(channel)
    
    async def one_hello():
        res=computation()
        response = await stub.SayHello(helloworld_pb2.HelloRequest(data=res))

    await asyncio.gather(*(one_hello() for _ in range(5)))