有没有办法在grpc服务器端设置超时?

时间:2019-05-29 07:22:56

标签: python-multithreading grpc-python

无法使服务器端的grpc连接超时。客户端可能建立连接但处于保持/睡眠状态,这可能导致grpc服务器连接挂起。服务器端是否可以在一定时间后断开连接或设置超时?

我们尝试从客户端断开连接,但无法从服务器断开连接。 Angad在此链接Problem with gRPC setup. Getting an intermittent RPC unavailable error中说,可以但无法在python中定义这些参数。

我的代码段:

def serve():
server = grpc.server(thread_pool=futures.ThreadPoolExecutor(max_workers=2), maximum_concurrent_rpcs=None, options=(('grpc.so_reuseport', 1),('grpc.GRPC_ARG_KEEPALIVE_TIME_MS', 1000)))
stt_pb2_grpc.add_ListenerServicer_to_server(Listener(), server)
server.add_insecure_port("localhost:50051")
print("Server starting in port "+str(50051))
server.start()
try:
    while True:
        time.sleep(60 * 60 * 24)
except KeyboardInterrupt:
    server.stop(0)
if __name__ == '__main__':
serve()

我希望在python中,连接也应该从grpc服务器端超时。

1 个答案:

答案 0 :(得分:0)

简而言之,您可能会发现context.abort(...)有用,请参阅API reference。 gRPC Python的基础C核心API不支持服务器处理程序超时。因此,您必须在Python中实现自己的超时机制。

您可以尝试其他StackOverflow问题中的一些解决方案。

或者使用简单但开销很大的额外线程在一定时间后中止连接。可能看起来像这样:

_DEFAULT_TIME_LIMIT_S = 5

class FooServer(FooServicer):

  def RPCWithTimeLimit(self, request, context):
    rpc_ended = threading.Condition()
    work_finished = threading.Event()

    def wrapper(...):
      YOUR_ACTUAL_WORK(...)
      work_finished.set()
      rpc_ended.notify_all()

    def timer():
      time.sleep(_DEFAULT_TIME_LIMIT_S)
      rpc_ended.notify_all()

    work_thread = threading.Thread(target=wrapper, ...)
    work_thread.daemon = True
    work_thread.start()

    timer_thread = threading.Thread(target=timer)
    timer_thread.daemon = True
    timer_thread.start()

    rpc_ended.wait()
    if work_finished.is_set():
      return NORMAL_RESPONSE
    else:
      context.abort(grpc.StatusCode.DEADLINE_EXCEEDED, 'RPC Time Out!')