Нашёл где-то в дебрях интернетов пример запуска асихронного сервера на Tornado с корутинами. Код:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import logging
import time
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.gen
from tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)
class MainHandler(tornado.web.RequestHandler):
@tornado.gen.coroutine
def outer(self):
logging.info('outer starts')
yield self.inner()
logging.info("some text here")
yield self.inner()
logging.info('outer ends')
return 'hello'
@tornado.gen.coroutine
def inner(self):
time.sleep(2)
logging.info('inner runs')
@tornado.web.asynchronous
@tornado.gen.coroutine
def get(self):
res = yield self.outer()
self.write(res)
if __name__ == "__main__":
tornado.options.parse_command_line()
app = tornado.web.Application(handlers=[(r"/", MainHandler)])
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
Судя по документации Tornado и куче прочитанных статей в интернетах, декоратор "@tornado.gen.coroutine" в купе с yield внутри функции, даёт асинхронное выполнение задач. Однако, запуск вышевставленного кода меня огорчил :-( Я ожидал, что лог из метода outer() ("some text here") напечатается раньше, чем из метода inner() (специльно таймаут вставил). И весь аутпут в лог выполнился очень даже синхронно. Более того, я убрал из кода все эти декораторы от Tornado, убрал все yield'ы, то есть сделал код чисто сихронным. Вуаля - результат от асинхронного кода не отличается: тесты проводил на двух вкладках браузера, запускал оновременный Reload и наблюдал за происходящим в консоли запущенного сервера. Мало того, что задачи для одного клиента выполнялись синхронней некуда, так ещё и клиенты блокировали друг друга (точнее выстраивались в очередь: сервер отправлял ответ одному клиенту и брался за следующего).
Почему я так думаю относительно ассинхронности: с этой магией хорошо знаком только в разрезе работы с ajax-запросами в JavaScript - запустил запрос, навесил на результат коллбэк, процесс работает и пыхтит дальше, коллбэк отработает по приходу результата от ajax-запроса. Мне казалось, что в Tornado будет так же красиво :-) Ткните меня носом в то место, где я неверно интерпретирую асинхронность в этом замечательном фрэймворке и помогите постигнуть дзен :-) буду очень благодарен!
ЗЫ: с корутинами пока на ВЫ общаюсь, не судите строго :-)