Tornado提供了強大的異步IO機制,提高了服務器的響應能力.
@tornado.web.asynchronous
tornado默認在處理函數返回時關閉鏈接,@tornado.web.asynchronous修飾器使得連接保持開啟, 即修飾器將RequestHandler 的 _auto_finish 屬性置為 false.
需要調用RequestHandler.finish()方法關閉連接。
class IndexHandler(tornado.web.RequestHandler):
def on_finish():
self.finish()
@tornado.web.asynchronous
def get(self):
self.write('Async Hello')
self.finish()
@tornado.gen.engine
Tornado 通過 @asynchronous decorator 來實現異步請求,但使用的時候必須將 RequestHandler 和 callback 分離開,tornado.gen 模塊可以幫助我們在一個函數里完成這兩個工作。
@tornado.gen使用python的generator來實現異步。
該修飾器必須包含在@asynchronous修飾器內層。
class GenAsyncHandler(RequestHandler):
@asynchronous
@gen.engine
def get(self):
http_client = AsyncHTTPClient()
response = yield gen.Task(http_client.fetch, "http://example.com")
do_something_with_response(response)
self.render("template.html")
tornado.gen.Task(func, *args, **kwargs)
Task的構造器接受一個異步調用func(如http_client.fetch), 並把args和kwargs傳給func.
在異步調用返回(發送消息)后yield Task對象,在異步調用返回結果賦給response,從下一行繼續執行(和原生的Python協程相同).
注意Task的func必須是異步調用,否則仍會造成阻塞。
tornado自帶的各種AsyncClient經常用於此種情形下。
@tornado.gen.coroutine
在tornado3發布之后,強化了coroutine的概念,在異步編程中,gen.coroutine替代了原來的gen.engine,兩者的使用是基本一致的。
從調用者角度說,@gen.coroutine類似於@return_future和@gen.engine.
ioloop
Tornado依賴ioloop實現了非阻塞式(同步多路IO復用)的請求響應,ioloop采用epoll或者select實現。
理解非阻塞和異步io的好機會……
