Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/324.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 如何在Tornado中编写非阻塞、分块的RequestHandler_Python_Tornado_Concurrent.futures - Fatal编程技术网

Python 如何在Tornado中编写非阻塞、分块的RequestHandler

Python 如何在Tornado中编写非阻塞、分块的RequestHandler,python,tornado,concurrent.futures,Python,Tornado,Concurrent.futures,下面是两个简单的RequestHandlers: class AsyncHandler(tornado.web.RequestHandler): @gen.coroutine def get(self): while True: future = Future() global_futures.add(future) s = yield future self.writ

下面是两个简单的
RequestHandlers

class AsyncHandler(tornado.web.RequestHandler):
    @gen.coroutine
    def get(self):
        while True:
            future = Future()
            global_futures.add(future)
            s = yield future
            self.write(s)
            self.flush()


class AsyncHandler2(tornado.web.RequestHandler):
    @gen.coroutine
    def get(self):
        for f in global_futures:
            f.set_result(str(dt.now()))
        global_futures.clear()
        self.write("OK")
第一个“订阅”流,第二个向所有订阅者发送消息

问题是我的订户不能超过一堆(在我的例子中是5-6个)。一旦我订阅了超过允许的数量,对第二个方法的下一个请求就会挂起

我假设发生这种情况是因为第一个处理程序没有正确地异步。这是因为我使用全局对象存储订阅者列表吗


我怎样才能同时打开更多的流式处理请求,逻辑限制是什么?

问题是,在您对其进行迭代时,
global\u futures
正在被修改:当
asynchHandler.get
唤醒时,它会从一个
yield
运行到下一个
,这意味着它将创建下一个未来,并在控件返回到
asynchHandler2
之前将其添加到集合中。这是未定义的,行为取决于迭代器在集合中的位置:有时新的未来被插入到迭代器的“后面”,一切正常,有时它被插入到迭代器的“前面”,同一个使用者处理程序将被第二次唤醒(并插入自身的第三个副本,可能在前面或后面…)。当你只有几个消费者时,你会经常碰到“背后”的情况,这样事情就可以解决了,但如果消费者太多,事情就很难完成

解决方案是在迭代之前复制
global\u futures
,而不是在最后清除:

@gen.coroutine
def get(self);
    fs = list(global_futures)
    global_futures.clear()
    for f in fs:
        f.set_result(str(dt.now()))
    self.write("OK")

请注意,我认为这只是Tornado4.x及更高版本中的一个问题。在Tornado 5中,事情发生了更改,因此
set\u result
不再立即调用等待的处理程序,因此不再进行并发修改。

谢谢你,Ben,我感谢你的帮助。这个问题与tornado完全无关,它实际上是对浏览器中每个主机并发连接的限制——这个问题与问题的主题无关,这里讨论的是原始问题-