我尝试使用应使用异步操作的自定义WSGICONTAINER:
from tornado import httpserver, httpclient, ioloop, wsgi, gen
@gen.coroutine
def try_to_download():
response = yield httpclient.AsyncHTTPClient().fetch("http://www.stackoverflow.com/")
raise gen.Return(response.body)
def simple_app(environ, start_response):
res = try_to_download()
print 'done: ', res.done()
print 'exec_info: ', res.exc_info()
status = "200 OK"
response_headers = [("Content-type", "text/html")]
start_response(status, response_headers)
return ['hello world']
container = wsgi.WSGIContainer(simple_app)
http_server = httpserver.HTTPServer(container)
http_server.listen(8888)
ioloop.IOLoop.instance().start()
但这不起作用。似乎应用程序不等待 try_to_download 函数结果。下面的代码也无效:
from tornado import httpserver, httpclient, ioloop, wsgi, gen
@gen.coroutine
def try_to_download():
yield gen.Task(httpclient.AsyncHTTPClient().fetch, "http://www.stackoverflow.com/")
def simple_app(environ, start_response):
res = try_to_download()
print 'done: ', res.done()
print 'exec_info: ', res.exc_info()
status = "200 OK"
response_headers = [("Content-type", "text/html")]
start_response(status, response_headers)
return ['hello world']
container = wsgi.WSGIContainer(simple_app)
http_server = httpserver.HTTPServer(container)
http_server.listen(8888)
ioloop.IOLoop.instance().start()
您有什么想法为什么它不起作用?我使用的Python版本是2.7。
P.S。您可以问我为什么我不想使用本机 tornado.web.requesthandler 。主要原因是我有自定义的Python库(WSGIDAV),该库会产生WSGI接口,并允许编写自定义适配器,我可以做异步。
wsgi不适用于异步。
通常,要等待龙卷风Coroutine完成的功能,该功能本身必须是coroutine,并且必须yield
COC_1 Coroutine的结果:
@gen.coroutine
def caller():
res = yield try_to_download()
但是,当然,WSGI函数像simple_app
这样的功能不能成为Coroutine,因为WSGI不了解Coroutines。瓶文档中对WSGI和异步之间的不兼容性更详尽。
如果您必须支持WSGI,请不要使用Tornado的Asynchttpclient,请使用同步客户端,例如标准的Urllib2或Pycurl。如果您必须使用龙卷风的AsynchttpClient,请勿使用WSGI。