Reputation: 1532
I'm using Tornado. I have a bunch of asynchronous request handlers. Most of them do their work asynchronously, and then report the result of that work back to the user. But I have one handler whose job it is to simply tell the user that their request is going to be processed at some point in the future. I finish the HTTP connection and then do more work. Here's a trivialized example:
class AsyncHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
def get(self, *args, **kwargs):
# first just tell the user to go away
self.write("Your request is being processed.")
self.finish()
# now do work
...
My question is: is this a legitimate use of Tornado? Will the code after the self.finish() run reliably? I've never had a problem with it before, but now I'm seeing a problem with it in one of my development environments (not all of them). There are a number of work-arounds here that I've already identified, but I want to make sure I'm not missing something fundamental to the request-lifecycle in Tornado. There doesn't SEEM to be a reason why I wouldn't be able to run code after calling self.finish(), but maybe I'm wrong.
Thanks!
Upvotes: 14
Views: 5606
Reputation: 134691
Yes, you can.
You have to define on_finish
method of your RequestHandler
. This is a function run after the request finished and has sent the response to client.
Called after the end of a request.
Override this method to perform cleanup, logging, etc. This method is a counterpart to prepare. on_finish may not produce any output, as it is called after the response has been sent to the client.
Upvotes: 31
Reputation: 9256
Yes, your code after self.finish()
will work reliably. But you can't call self.finish()
twice - it will raise an exception. You can use self.finish()
to close connection before all work on server is done.
But as Cole Maclean told - don't do heavy work after finish. Look for another way to do heavy tasks in background.
Upvotes: 6