2014-01-30 4 views
1

나는 비동기 작업과 함께 작동합니다 사용자 정의 WSGIContainer 사용하려고 :tornado.wsgi.WSGIContainer에서 async tornado API를 사용하는 방법?

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_loadload 함수 결과. 아래 코드도 작동하지 않습니다.

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() 

작동하지 않는 이유가 있습니까? 내가 사용하는 파이썬 버전은 2.7이다.

P. 왜 내가 네이티브를 사용하고 싶지 않은지 물어볼지도 모른다 tornado.web.RequestHandler. 가장 큰 이유는 WSGI 인터페이스를 생성하고 비동기로 만들 사용자 지정 어댑터를 작성할 수있는 사용자 지정 파이썬 라이브러리 (WsgiDAV)가 있다는 것입니다.

답변

4

WSGI는 비동기와 작동하지 않습니다.

@gen.coroutine 
def caller(): 
    res = yield try_to_download() 

그러나 물론 simple_app 같은 WSGI 기능이 될 수 없습니다 : 함수는 함수 자체가 코 루틴 있어야 완료하는 토네이도 코 루틴 대기하고 코 루틴의 결과를 yield합니다 위해 일반적으로

, 왜냐하면 WSGI는 코 루틴을 이해하지 못하기 때문입니다. WSGI와 비동기 간의 비 호환성에 대한 자세한 설명은 Bottle documentation입니다.

WSGI를 지원해야하는 경우 Tornado의 AsyncHTTPClient를 사용하지 말고 표준 urllib2 또는 PyCurl과 같은 동기식 클라이언트를 사용하십시오. Tornado의 AsyncHTTPClient를 사용해야하는 경우에는 WSGI를 사용하지 마십시오.

+0

답변 해 주셔서 감사합니다. 네 말이 맞아 보인다. 그러나 현재 토네이도 비동기 프로그래밍 API를 사용할 수 없다면 왜 WSGIContainer와 같은 기능이 토네이도 응용 프로그램에서 사용될 수 있는지 모르겠습니다. 그래서 주요 응용 프로그램을 차단합니다. – Dmitry

+3

사용중인 WSGI 앱이 이벤트 루프를 차단하는 데 충분히 빠르면 WSGIContainer를 사용할 수 있습니다. Tornado 앱과 동일한 프로세스에서 WSGI 앱을 사용하면 몇 가지 이점이 있습니다. 특히 WSGIContainer를 사용하여 Tornado 앱에 Dowser를 연결하여 메모리 누수를 감지 할 수 있습니다. –