2

In a simple async case, handler might look like:

@tornado.web.authenticated
@tornado.web.asynchronous
def post(self):
    AsyncHTTPClient().fetch("http://api.example.com/", self.on_post_response)

def on_post_response(self, response):
    self.render("template.html", status=response.error)

However, I have come to a point when I need to perform two async operations (fetching remote rest api, and then sending mail with the results) before returning to the client.

I wonder if there is a "buit-in" way to do this, e.g. by adding callbacks to a queue (like ioloop.add_callback) or do I have to compose a custom object which will manage those tasks and their state and call it from post.

Tzury Bar Yochay
  • 8,798
  • 5
  • 49
  • 73

1 Answers1

4

Have you considered the following approach?

@tornado.web.authenticated
@tornado.web.asynchronous
def post(self):
    async_fetch(..., self._on_fetch_response)

def _on_fetch_response(self, response):
    async_mail(response, self._on_mail_response)

def _on_mail_response(self, response):
    self.render(...) # render() automatically calls self.finish()

Or using tornado.gen:

@asynchronous
@gen.engine
def post(self):
    fetch_response = yield gen.Task(async_fetch, ...)
    mail_response = yield gen.Task(async_mail, ...)
    self.render(...)
jholster
  • 5,066
  • 1
  • 27
  • 20
  • can you help defining the async_mail then, it seems as if this is the actual help I need ;-), is adding @asynchronous decorator makes every function async? – Tzury Bar Yochay Feb 21 '12 at 15:05
  • 2
    The `async_email()` was just a fictional example, see [tornadomail](https://github.com/equeny/tornadomail) for asynchronous SMTP client. The @asynchronous decorator makes the request handler method itself asynchronous, but the code inside the handler still blocks unless it explicitly supports non-blocking execution, e.g. via callback parameter. Thus you need special versions of IO libraries (mail, http, database) to take advantage of asynchronousness. The `gen.Task` is just syntactic sugar for the same thing. – jholster Feb 21 '12 at 18:16