Я пытаюсь записать простое веб-приложение, пользующееся библиотекой Tornado и JS Prototype. Так, клиент может выполнить длительное задание на сервере. Я желаю, что это прогоны задания Асинхронно - так, чтобы клиенты других могли просмотреть страницу и сделать некоторый материал там.
Здесь, что я имею:
#!/usr/bin/env/ pytthon
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
from tornado.options import define, options
import os
import string
from time import sleep
from datetime import datetime
define("port", default=8888, help="run on the given port", type=int)
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.render("templates/index.html", title="::Log watcher::", c_time=datetime.now())
class LongHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
def get(self):
self.wait_for_smth(callback=self.async_callback(self.on_finish))
print("Exiting from async.")
return
def wait_for_smth(self, callback):
t=0
while (t < 10):
print "Sleeping 2 second, t={0}".format(t)
sleep(2)
t += 1
callback()
def on_finish(self):
print ("inside finish")
self.write("Long running job complete")
self.finish()
def main():
tornado.options.parse_command_line()
settings = {
"static_path": os.path.join(os.path.dirname(__file__), "static"),
}
application = tornado.web.Application([
(r"/", MainHandler),
(r"/longPolling", LongHandler)
], **settings
)
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
if __name__ == "__main__":
main()
Это - часть сервера. Это имеет основное представление (показывает мало приветствия, текущее время сервера и URL для запроса ajax, который выполняет длительное задание. При нажатии кнопки длительное задание выполняется. И сервер зависает: (Я не могу просмотреть страницы, в то время как это задание работает. Вот шаблонная страница:
{{ title }}
Current time is {{c_time}}
что я делаю неправильно? Как может реализовать долго объединение, с помощью Торнадо и Прототипа (или jQuery)
PS: Я посмотрел на пример Чата, но он также усложнил. Не может понять, как это работает: (
Загрузка PSS полный пример
Tornado является однопоточным веб-сервером. Ваш цикл while в wait_for_smith
блокирует Tornado.
Вы можете переписать этот метод следующим образом:
def wait_for_smth(self, callback, t=10):
if t:
print "Sleeping 2 second, t=%s" % t
tornado.ioloop.IOLoop.instance().add_timeout(time.time() + 2, lambda: self.wait_for_smth(callback, t-1))
else:
callback()
Вам нужно добавить время импорта
вверху, чтобы это работало.
Я преобразовал пример чата Tornado для работы на gevent . Взгляните на живую демонстрацию здесь и объяснение и исходный код здесь .
Он использует легкие потоки пользовательского уровня ( гринлеты ) и сравним по скорости / использованию памяти с Tornado. Однако код прост, вы можете вызывать sleep () и urlopen () в своих обработчиках, не блокируя весь процесс, и вы можете создавать долго выполняющиеся задания, которые делают то же самое. Под капотом приложение является асинхронным, питается от цикла обработки событий, написанного на C ( libevent ).
Вы можете прочитать введение здесь .