0

If I add_done_callback to a grpc future object, did I need to close channel?

class CallBack(object):
    def __init__(self,channel=None) -> None:
        self._channel = channel

    def __call__(self, future):
        print(self.future.result())
        # self._channel.close()
def test():
    channel = grpc.insecure_channel('localhost:50051')
    stub = helloworld_pb2_grpc.GreeterStub(channel)
    call_future = stub.SayHello.future(helloworld_pb2.HelloRequest(name='you'))
    call_back = CallBack(channel)
    call_future.add_done_callback(call_back)

If I use with-statement to initialize channel, channel will close before callback.

def test():
    with grpc.insecure_channel('localhost:50051') as channel:
        stub = helloworld_pb2_grpc.GreeterStub(channel)
        call_future = stub.SayHello.future(helloworld_pb2.HelloRequest(name='you'))
        call_back = CallBack(channel)
        call_future.add_done_callback(call_back)

Which will raise error:

cription":"Channel closed!","file":"src/core/lib/surface/call.cc","file_line":727,"grpc_message":"Channel closed!","grpc_status":1}"
ehds
  • 665
  • 1
  • 6
  • 16

1 Answers1

1

In general, you need to close the channel at some point. The alternative is leaking per-channel memory as you spin up more channels in your process over time. The problem in your second example with the with statement is that the channel is closed before the callback has a chance to fire.

If the callback executing is the point at which the channel is no longer needed, then you should close the channel from that callback or set a bit of state indicating that another thread should close the channel.

Richard Belleville
  • 1,445
  • 5
  • 7