grpcgrpc-python

gRPC not receiving responses due to queue_timeout?


I have a simple gRPC client/server application. The server starts and the client pings(verified by server-side code); however I don't receive responses.

I narrowed it down to this line on the server-side. I am not sure what could cause a queue_timeout. I am following this

.proto:

   1 syntax = "proto3";
   2
   3 service Pinger {
   4   rpc Ping (PingMessage) returns (PongMessage) {}
   5 }
   6
   7 message PingMessage{
   8     string message = 1;
   9 }
  10
  11 message PongMessage {
  12   string message = 1;
  13 }

server.py:

 class Pinger(PingerServicer):
     def Ping(self, request, context):
         return grpc_service_pb2.PongMessage(message = "pong")

 grpc_server_app = Pinger()

client.py:

 class GRPCClient:
     def __init__(self):
         self.host = "localhost"
         self.port = GRPC_PORT

     @timeit('grpc')
     def send(self, channel):
         stub = grpc_service_pb2_grpc.PingerStub(channel)
         ping_message = grpc_service_pb2.PingMessage(message = 'ping')
         response = stub.Ping(ping_message)

     def run(self):
         with grpc.insecure_channel(f"{self.host}:{self.port}") as channel:
             while True:
                 self.send(channel)

main.py

  17 def grpc_server_wrapper():
  18     server = grpc.server(ThreadPoolExecutor(max_workers=2))
  19     grpc_service_pb2_grpc.add_PingerServicer_to_server(grpc_server_app, server)
  20     server.add_insecure_port('[::]:' + str(GRPC_PORT))
  21     server.start()
  22     print("Server started, listening on " + str(GRPC_PORT))
  23     server.wait_for_termination()
  24
  25 if __name__ == '__main__':
  26     futures = []
  27     with ProcessPoolExecutor(max_workers = 2) as executor:
  46         futures.append(
  47             executor.submit(grpc_client_app.run)
  48         )
  49
  50         futures.append(
  51             executor.submit(grpc_server_wrapper)
  52         )
  56     [f.result() for f in futures]

Solution

  • The problem was that the server was not ready when the client was trying to ping and thus it would err out and die. The error was swallowed by the process pool.

    The solution is to add wait_for_ready = True to the client call:

    response = stub.Ping(ping_message, wait_for_ready = True)