【问题标题】:Tornado - How to stop all asynchronous 'await's from on_connection_closeTornado - 如何从 on_connection_close 停止所有异步“等待”
【发布时间】:2019-07-01 11:41:52
【问题描述】:

所以我在 Tornado 中有一个异步请求处理程序,它等待一些事件,之后它向客户端写入内容并终止。

基本上是这样的:

async def post(self, request_url):
    await my_semaphore.acquire()
        try:
            with await my_redis_pool as redis:
                redis_value = await redis.brpop("my_value", timeout=very_long_timeout)
            self.write(value)
    finally:
        my_semaphore.release()
        print("The semaphore is released !")

一切正常,除了一件事:如果客户端终止连接,处理程序继续等待它正在等待的任何事件。

我发现客户端关闭连接时会调用 on_connection_close ;那么我可以从这个函数中调用什么来将主处理程序从等待中“打破”?有没有办法提出类似于异常的东西?

    def on_connection_close(self):
        print("on_connection_close")
        # what could I do here to interrupt whatever the post() method is awaiting

我尝试从 on_connection_close 调用raise tornado.web.HTTPError(504),但它不起作用。 立即显示“on_connection_close”,但“信号量已释放!”仅在very_long_timeout 之后显示。

提前致谢!

【问题讨论】:

    标签: python-3.x asynchronous async-await tornado python-asyncio


    【解决方案1】:

    您需要跟踪未来。然后在on_connection_close 中,您可以在未来设置一个空结果。这将使协程向前移动。

    self.redis_value_future = redis.brpop("my_value", timeout=very_long_timeout)
    redis_value = await self.redis_value_future
    

    然后像这样设置一个空结果:

    def on_connection_close(self):
        self.redis_value_future.set_result('')
    

    【讨论】:

    • 谢谢!而不是 future.set_result() 我使用了 future.cancel() 似乎更合适(并在等待时捕获了 CancelledError)
    猜你喜欢
    • 2013-02-26
    • 1970-01-01
    • 2018-08-13
    • 2020-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    • 2020-03-26
    相关资源
    最近更新 更多