python - 在gRPC无限流期间检测客户端丢弃

时间:2017-05-29 12:57:44

标签: python stream grpc

我实现了无限流响应,就像使用gRPC架构的pub / sub模式一样。

有一个端点可以打开响应流并将其保留到客户端丢弃。为此,我存储了一个键值哈希,其中键是gRPC上下文,值是我用来轮询发送消息的队列。

我的端点代码如下:

def StreamTrades(self, request, context):
    self.feeds[context] = queue.Queue()

    callback_queue = queue.Queue()

    def remove_feed():
        if self.feeds.get(context) is not None:
            del self.feeds[context]

    def stop_stream():
        remove_feed()

        def raise_stop_stream_exception():
            raise StopStream('stopping stream')

        callback_queue.put(raise_stop_stream_exception)

    context.add_callback(stop_stream)

    def output_generator():
        while True:
            try:
                try:
                    callback = callback_queue.get(False)
                    callback()
                except queue.Empty:
                    pass
                if self.feeds.get(context) is not None:
                    trade = self.feeds[context].get()
                    if isinstance(trade, trades_pb2.Trade):
                        yield trade
                else:
                    raise StopStream('stopping stream')
            except IndexError:
                pass
            except StopStream:
                return

    return output_generator()

此代码适用于订阅和发布客户端更改。但是有一个与取消订阅有关的问题。检测客户端丢弃的好方法是什么?使用Context.add_callback(callBack)似乎不起作用,因为只有在服务器完成并关闭流时才会调用回调。当客户端不再存在时,生成器不会引发任何类型的状态。我在Java中看到,当在streamObserver中调用onNext并且没有客户端抛出Status.CANCELLED的StatusRuntimeException时,它允许对我来说已经足够的延迟取消订阅。

有没有办法检测客户端在响应流中丢弃连接?

1 个答案:

答案 0 :(得分:3)

当客户端断开连接时,应调用您向ServicerContext.add_callback注册的回调;没有被调用表明你患有this bug的情况是"回调仅在服务器完成并关闭流时被调用"。

相关问题