Reputation: 1799
So I have been investigating into how to write async code, and i have come up with the code below:
I have the following two questions:
from tornado import gen
import tornado.web
import tornado.ioloop
import motor
class MainHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
@gen.coroutine
def get(self):
post = yield db.user.find_one()
print post
self.write(post['name'])
handlers=[(
(r'/', MainHandler)
)]
db = motor.MotorClient().example
if __name__ == '__main__':
application = tornado.web.Application(handlers,debug=True)
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
Upvotes: 2
Views: 2772
Reputation: 25669
The best way to write async code is to write classes/functions. Then call the class/function. This method allows the event loop to handle the callback. Look at code sample below, there is function created, and then the function is used as callback. This (agian) is allowing the Event Loop do a callback in async way.
from tornado.httpclient import AsyncHTTPClient
def asynchronous_fetch(url, callback):
http_client = AsyncHTTPClient()
def handle_response(response):
callback(response.body)
http_client.fetch(url, callback=handle_response)
Upvotes: 0
Reputation: 22154
Asynchronousness is a property of the interface; using @gen.coroutine
is sufficient to make this handler asynchronous because it changes the interface (to return a Future
. As an aside, you don't need to use the @asynchronous
decorator here; since Tornado 3.1 the @coroutine
decorator alone has been enough). Furthermore, since Motor returns Futures
to be yielded, we know that it is also asynchronous.
Blocking is a property of the implementation; what you're really asking is how we know whether this handler is non-blocking. This, unfortunately is a trickier question. We know from Motor's documentation that it is designed and intended to be non-blocking, but there is no simple way to verify that it is in fact fully non-blocking. There is more discussion of what it means to be asynchronous and non-blocking at http://www.tornadoweb.org/en/stable/guide/async.html.
Tornado uses a single main thread because a single-threaded non-blocking system can achieve higher performance than a threaded one (especially when considering the limitations imposed by the python GIL), and the complexity of making everything asynchronous is offset by the fact that you don't generally need to worry about thread-safety issues.
Upvotes: 4