Search code examples
tornado

Callback in Tornado


I am trying to make the following code asynchronous using @return_future.I have time.sleep() because my application demands a blocking feature. But I do not know what to callback so as to make it async.as I am a beginner in TORNADO.

In the following code there are two html files "register.html" and welcome.html. Any help would be appreciated.`#Asynchronous

import time
import json
import tornado.web
import tornado.ioloop
from tornado import gen
from tornado.concurrent import return_future
from BaseHTTPServer import BaseHTTPRequestHandler

execfile("jdict.py")

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.render("welcome.html")

class LoginHandler(MainHandler):
    def get(self):
        self.render("register.html")                                  
    @return_future
    def post(self,callback=None):
    dict={}
       wmap_dict=import_dict('user_data')
       dict["uname"]=self.get_argument("uname")
       dict["uid"]=self.get_argument("uid")
       u_key=dict["uid"] +':' +self.get_argument("uname")
       jline={}
       jline[u_key]=dict
       print (jline)
       with open("user_data",'a')as f:
            f.write(json.dumps(jline))
            f.write("\n")
    time.sleep(5)
    callback()
    self.redirect("/")



application = tornado.web.Application([
    (r"/", MainHandler),
    (r"/login", LoginHandler),
], cookie_secret="__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__")

application.listen(5500)
tornado.ioloop.IOLoop.current().start()

`


Solution

  • @return_future takes callback-style asynchronous code and makes it usable in a coroutine. It does not make synchronous code asynchronous. For that, you need a concurrent.futures.ThreadPoolExecutor:

    # executor can be a global
    executor = concurrent.futures.ThreadPoolExecutor()
    
    class MyHandler(RequestHandler):
        @gen.coroutine
        def post(self):
            yield executor.submit(self.do_something_slow)
            self.redirect("/")
    
        def do_something_slow(self):
            time.sleep(5)
    

    See the Tornado FAQ for more.