如何在龙卷风python中创建异步RequestHandler

时间:2015-08-14 15:20:00

标签: python python-3.x asynchronous tornado

目前我正在使用龙卷风在我的后端网络服务器上工作。

我现在遇到的问题:
- 当发出请求并且服务器正在处理请求时,所有其他请求都被阻止

我的RequestHandler:

class UpdateServicesRequestHandler( RequestHandler ):

    @gen.coroutine
    def get( self ):

        update = ServiceUpdate()
        response = yield update.update_all( )

        if self.request.headers.get('Origin'):
            self.set_header( 'Access-Control-Allow-Origin', self.request.headers.get('Origin') )
        self.set_header( 'Content-Type', 'application/json')
        self.write( response )

我的update_all()

@gen.coroutine
def update_all( self ):

    for service in self.port_list:
        response = yield self.update_service( str( service.get( 'port' ) ) )
        self.response_list.append( response )

    self.response = json.dumps( self.response_list )

    return self.response

我的update_sevice()

process = Popen( [ command ], stdout=PIPE, stderr=PIPE, shell=True )
output, error = process.communicate()

问题是,我需要update_all()方法的结果。 那么有可能使这个请求不会阻止我的整个服务器请求吗?

谢谢!

2 个答案:

答案 0 :(得分:4)

除了使用tornado.process.Subprocess作为dano建议之外,您应该使用stdout=tornado.process.Subprocess.STREAM而不是PIPE,并异步读取stdout / stderr。使用PIPE将适用于少量输出,但如果使用wait_for_exit()并且子进程尝试写入太多数据(过去为4KB但限制为在大多数现代Linux系统中更高。)

PIPE

答案 1 :(得分:2)

你需要在subprocess.Popen周围使用tornado的包装器来避免阻塞事件循环:

from tornado.process import Subprocess
from subprocess import PIPE
from tornado import gen

@gen.coroutine
def run_command(command):
    process = Subprocess([command], stdout=PIPE, stderr=PIPE, shell=True)
    yield process.wait_for_exit()  # This waits without blocking the event loop.
    out, err = process.stdout.read(), process.stderr.read()
    # Do whatever you do with out and err