So I have an asynchronous request handler in Tornado, that awaits for some events, after what it writes something to the client and terminates.
Basically it's something like this :
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 !")
Everything works fine, except for one thing : if the client terminates the connection, the handler continues to await on whatever event it was waiting.
I found on_connection_close is called when the client closes the connexion ; so what can I call from this function to "break" the main handler out from the awaits? Is there a way to raise something, similar to an exception?
def on_connection_close(self):
print("on_connection_close")
# what could I do here to interrupt whatever the post() method is awaiting
I've tried to call a raise tornado.web.HTTPError(504)
from on_connection_close, but it doesn't work.
"on_connection_close" is displayed immediately, but "The semaphore is released !" is displayed only after very_long_timeout.
Thanks in advance!
You need to keep track of the future. And then in on_connection_close
you can set an empty result on the future. This will move the coroutine forward.
self.redis_value_future = redis.brpop("my_value", timeout=very_long_timeout)
redis_value = await self.redis_value_future
And then set an empty result like this:
def on_connection_close(self):
self.redis_value_future.set_result('')