Tornado - 如何停止来自 on_connection_close 的所有异步“等待”
Tornado - How to stop all asynchronous 'await's from on_connection_close
所以我在 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 在客户端关闭连接时被调用;那么我可以从这个函数调用什么来 "break" 主处理程序从等待中出来?有没有办法引发类似于异常的东西?
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"立即显示,但"The semaphore is released !"仅在very_long_timeout之后显示。
提前致谢!
你需要跟踪未来。然后在 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('')
所以我在 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 在客户端关闭连接时被调用;那么我可以从这个函数调用什么来 "break" 主处理程序从等待中出来?有没有办法引发类似于异常的东西?
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"立即显示,但"The semaphore is released !"仅在very_long_timeout之后显示。
提前致谢!
你需要跟踪未来。然后在 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('')