被 tornado.concurrent.Future 异常搞糊涂了

confused by tornado.concurrent.Future exception

我正在尝试使用 tornado Futures 实现 的变体。队列有问题,因为我不想过去的数据被积累。 IOW,我希望一个 http 请求处理程序阻止等待原始请求启动后发生的另一个结果。

但我想我错过了一步。

我的代码如下:

Events = dict()

class EventHandler(tornado.web.RequestHandler):
    @tornado.gen.coroutine
    def get(self, unit):
        # create  future to block on
        future = tornado.concurrent.Future()
        # store the future at a place the produce can find it
        Events[unit] = future
        # block waiting for the future's response
        result = yield future.result()
        # deregister the future
        Events.pop(unit, None)
        self.write(result)

    @tornado.gen.coroutine
    def post(self, unit):
        # fetch the corresponding future if there is one
        future = Events.get(unit, None)
        if future:
            # found one, set the result to pass body over
            future.set_result(self.request.body)
        else:
            print('noop')
        self.write(bytes())

发生的事情是我收到如下所示的错误:

  File "./foo.py", line 44, in get
    result = yield future.result()
  File "/usr/lib/python3/dist-packages/tornado/concurrent.py", line 216, in result
    self._check_done()
  File "/usr/lib/python3/dist-packages/tornado/concurrent.py", line 294, in _check_done
    raise Exception("DummyFuture does not support blocking for results")

我没有正确使用 Future 吗?在配置它时我需要执行其他步骤吗?我应该创建一个实现 _check_done 行为的子类吗?我认为龙卷风 Future 是其他系统马蹄莲 promise 的同义词的假设不正确吗?除了使用 future/promise?

有什么不同的方法吗?

你需要使用

result = yield future

没有

result = yield future.result()

yield future.result()其实等价于yield <whatever is returned by future.result()>。如果结果还没有准备好,那意味着 result() API 必须阻塞(意思是阻塞龙卷风事件循环)直到结果准备好,而 tornado.concurrent.Future 不会不支持。您只能使用非阻塞 yield future 构造等待结果。