связывание асинхронных операций перед записью в клиент (python - tornado) - PullRequest
2 голосов
/ 21 февраля 2012

В простом асинхронном случае обработчик может выглядеть так:

@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)

Однако я дошел до того, что мне нужно выполнить две асинхронные операции (извлечь API удаленного отдыха, а затем отправить почту с результатами) перед возвратом к клиенту.

Интересно, есть ли способ «сделать это», например добавив обратные вызовы в очередь (например, ioloop.add_callback) или мне нужно составить пользовательский объект, который будет управлять этими задачами и их состоянием, и вызывать его из post.

1 Ответ

4 голосов
/ 21 февраля 2012

Рассматривали ли вы следующий подход?

@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()

Или используя tornado.gen :

@asynchronous
@gen.engine
def post(self):
    fetch_response = yield gen.Task(async_fetch, ...)
    mail_response = yield gen.Task(async_mail, ...)
    self.render(...)
...