I'm having an issue with client disconnection using a Python gRPC server 
with a unary-stream procedure. I may have missed something in the 
documentation, but multiple attempts of checking whether or not the client 
is still active have all failed. 

My hope is to find a way for the Servicer to detect when to stop generating 
values when a client disconnects. A client subscribes to a stream of 
updates once and receives all changes to the server state for an unbounded 
amount of time. The actual server implementation should also send values 
regularly on a heartbeat with low activity. A minimal example is given 
below that demonstrates my problem.

class TaskService(proto_grpc.TaskServiceServicer):
    def Subscribe(self, request, context):
        print 'subscribed'

        while True:
            time.sleep(1)
            print 'sending'
            yield proto.TaskState(state='IDLE')

        print 'finished'


def main():
    server = 
grpc.server(concurrent.futures.ThreadPoolExecutor(max_workers=3))

    proto_grpc.add_TaskServiceServicer_to_server(
        TaskService(),
        server,
    )

    server.add_insecure_port('0.0.0.0:3253')
    server.start()

    try:
        while True:
            time.sleep(1)
            print 'bump'
    finally:
        print 'stopping'
        server.stop(grace=0)
        print 'stopped'


There are two issues at play here. First, if a client subscribes and then 
is disconnected forcefully, the server will continue to send updates to 
that channel. This means if three clients have *ever* subscribed to this 
server, then a fourth may never connect in the future (due to the low 
number in the thread pool). This seems wrong, but I may be missing a 
setting somewhere.

Second, if a client subscribes and then disconnects, the server will never 
shut down completely. The process will hang in an un-killable state. This 
does not occur when a client never connects, or if a client connects but 
stays connected as the process shuts down.

The following output occurs when the server is killed after a client 
connects:

subscribed
bump
sending
bump
sending
^C
stopping
stopped
Traceback (most recent call last):
    ...
      time.sleep(1)
KeyboardInterrupt
sending
<process terminated gracefully>

The following output occurs when the server is killed after a client 
disconnects:

subscribed
bump
sending
bump
<client is killed>
sending
bump
^C
stopping
stopped
Traceback (most recent call last):
  ...
    time.sleep(1)
KeyboardInterrupt
sending
<process hangs indefinitely>

I hope there is an easy solution as I simply misunderstood the correct use 
to implement a streaming response and apologize in advance if there is.

-- 
You received this message because you are subscribed to the Google Groups 
"grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/grpc-io.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/grpc-io/4f06cf78-14b0-4f6f-aaaa-77d4b54f9647%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to