在Tornado处理长请求永远不会完成

时间:2014-12-27 14:31:42

标签: python tornado

我使用Tornado编写了以下HTTP服务器:

def reindex(index):
    # After some initialization, we execute a process and wait for its output
    result = subprocess.check_output([indexerBinPath, arg])

class ReindexRequestHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    def post(self):
        reindexRequest = json.loads(self.request.body)
        p = self.application.settings.get('pool')
        p.apply_async(reindex, [ reindexRequest['IndexName'] ], callback = self.onIndexingFinished)         

    def onIndexingFinished(self, output):       
        self.flush()        
        self.finish()
        logger.info('Async callback: finished')

application = tornado.web.Application([ 
  (r"/reindex", ReindexRequestHandler)
], pool = Pool(8), queue = Queue())

if __name__ == "__main__":
    application.listen(8625)
    try:
        tornado.ioloop.IOLoop.instance().start()
    except KeyboardInterrupt:
        tornado.ioloop.IOLoop.instance().stop()

POST处理程序中,我异步执行reindex函数,该函数又启动一个进程并等待它完成。这很好 - 这个过程总是正确执行。根据其论点,该过程可能需要几分钟才能完成。如果它在几秒钟内完成,一切正常。

然而,当需要时,例如超过3分钟完成,发送POST请求的HTTP客户端永远不会得到答案。从服务器的角度来看,它看起来还不错 - 我可以看到异步回调:已完成已记录。但是,HTTP客户端无限期地等待响应(直到它因超时而失败)。我曾尝试过Fiddler的请求编写器和.NET HttpClient类。

如果请求需要很长时间才能处理,为什么HTTP客户端永远不会得到响应?

1 个答案:

答案 0 :(得分:1)

我有一个类似的处理程序,self.finish()会将响应触发回客户端。因此,如果您将该行移动到p.apply_async之上,它应该按照您的意图运行。