Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python gRPC一元流在断开连接/中断时阻塞后继续_Python_Grpc - Fatal编程技术网

Python gRPC一元流在断开连接/中断时阻塞后继续

Python gRPC一元流在断开连接/中断时阻塞后继续,python,grpc,Python,Grpc,我有一个简单的一元流方法Subscribe,它发送连接的客户端在队列上看到的最新项目。如果一秒钟内没有推送新项目,则会再次发送最近看到的项目以获取心跳信号 class Service(proto_grpc.ServiceServicer): def __init__(self, queue): self.queue = queue def Subscribe(self, request, context): index = 0 s

我有一个简单的一元流方法
Subscribe
,它发送连接的客户端在队列上看到的最新项目。如果一秒钟内没有推送新项目,则会再次发送最近看到的项目以获取心跳信号

class Service(proto_grpc.ServiceServicer):
    def __init__(self, queue):
        self.queue = queue

    def Subscribe(self, request, context):
        index = 0
        state = self.queue.get(index, timeout=None)

        while state:
            temp = self.queue.get(index, timeout=1)
            if temp:
                state = temp
                index = index + 1

            yield state
该计划的其余相关部分如下所示

def main(server, queue):
    server.start()

    try:
        while True:
            queue.append('foo')
        time.sleep(1)
    finally:
        server.stop(None)
日志记录显示,如果客户机订阅然后断开连接(不正常),Subscribe方法将继续处理。每次断开连接似乎对新客户端都不可用

同样奇怪的是,如果服务器进程被中断,那么服务器就会停止,客户端就会断开,服务器就会阻塞
yield
语句

什么是处理从流式RPC中删除不正常客户端的正确方法

编辑:显示相同行为的服务程序的简化版本

class Service(proto_grpc.ServiceServicer):
    def Subscribe(self, request, context):
        print 'subscribed'

        while context.is_active():
            time.sleep(1)
            print 'sending'
            yield some_proto_payload
            print 'sent'

        print 'finished'

一旦连接,无论客户端的连接状态如何,都将打印“发送/发送”对。当服务器在断开连接后停止时,输出挂起在最后一个“发送”和“发送”消息之间。

您是否应该使用
上下文。is_active()
方法确定您正在服务的RPC是否仍然处于活动状态?您可能已经发现了一个或两个单独的bug;我将进一步查看。我已尝试上下文。是否处于活动状态()。然而,在一次强有力的分离中,这似乎从来都不是真的。我目前正试图使用Golang服务器复制相同的行为,一旦写入失败,stream.Context().Done()通道将正确关闭。您能否进一步说明“服务器阻塞
yield
语句”的含义?您是否看到线程阻塞和服务器关闭挂起之类的情况?或者
grpc.Server.stop(None)
方法是否会在一段合理的时间后以普通返回方式终止?请记住,并不能保证应用程序级响应迭代器将被调用到耗尽状态。该过程不会终止,最后打印的输出是直接发送到客户端之前的消息。我将在上面发布一个最小的工作示例。