Dan K.
Dan K.

Reputation: 1532

Tornado: Can I run code after calling self.finish() in an asynchronous RequestHandler?

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

Answers (2)

vartec
vartec

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.

RequestHandler.on_finish()

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

Nikolay Fominyh
Nikolay Fominyh

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

Related Questions