龙卷风超时到很多递归请求

时间:2016-03-25 22:00:15

标签: python tornado coroutine

我正在尝试测试龙卷风中的异步处理,我编写了一个HTTP服务器,用于计算递归HTTP调用的斐波纳契数。 它适用于像6这样的小数字,但挂在8。 我确信异步在这里工作,否则它会卡在n = 3。 我无法解释为什么它停留在8.斐波那契增长很快但是8它仍然没有太多的耗尽端口或打开文件处理程序。

这里有什么障碍?

python 2.7和龙卷风4.3

import tornado.ioloop
import tornado.web
from tornado import gen
from tornado.httpclient import AsyncHTTPClient

class MainHandler(tornado.web.RequestHandler):
    http_client = AsyncHTTPClient()
    @gen.coroutine
    def get(self):
        n = int(self.get_argument('n', 1))
        print 'n = ', n
        if n <= 2:
            self.write("1")
        else:
            npUrl = 'http://localhost:8888/?n=%s' % (n - 1)
            nppUrl = 'http://localhost:8888/?n=%s' % (n - 2)
            print " get np %s an npp %s " % (npUrl, nppUrl)
            np, npp = yield [ self.http_client.fetch(npUrl),
                              self.http_client.fetch(nppUrl) ]
            npAndNpp = int(np.body) + int(npp.body)
            print 'np + npp  = %s + %s = %s' % (np.body, npp.body, npAndNpp)
            self.write("%s" % npAndNpp)
#        raise tornado.gen.Return(None)

def make_app():
    return tornado.web.Application([
        (r"/", MainHandler),
    ])

app = make_app()
app.listen(8888)
tornado.ioloop.IOLoop.current().start()

记录输出

egnyte@diehard:~/demo/tornado$ python async-fibonacci.py 
n =  7
 get np http://localhost:8888/?n=6 an npp http://localhost:8888/?n=5 
n =  6
 get np http://localhost:8888/?n=5 an npp http://localhost:8888/?n=4 
n =  5
 get np http://localhost:8888/?n=4 an npp http://localhost:8888/?n=3 
n =  5
 get np http://localhost:8888/?n=4 an npp http://localhost:8888/?n=3 
n =  4
 get np http://localhost:8888/?n=3 an npp http://localhost:8888/?n=2 
n =  4
 get np http://localhost:8888/?n=3 an npp http://localhost:8888/?n=2 
n =  3
 get np http://localhost:8888/?n=2 an npp http://localhost:8888/?n=1 
n =  4
 get np http://localhost:8888/?n=3 an npp http://localhost:8888/?n=2 
n =  3
 get np http://localhost:8888/?n=2 an npp http://localhost:8888/?n=1 
n =  3
 get np http://localhost:8888/?n=2 an npp http://localhost:8888/?n=1 
n =  2
n =  3
 get np http://localhost:8888/?n=2 an npp http://localhost:8888/?n=1 
n =  7
 get np http://localhost:8888/?n=6 an npp http://localhost:8888/?n=5 
ERROR:tornado.application:Multiple exceptions in yield list
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/tornado/gen.py", line 789, in callback
    result_list.append(f.result())
  File "/usr/local/lib/python2.7/dist-packages/tornado/concurrent.py", line 232, in result
    raise_exc_info(self._exc_info)
  File "<string>", line 3, in raise_exc_info
HTTPError: HTTP 599: Timeout
ERROR:tornado.application:Multiple exceptions in yield list
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/tornado/gen.py", line 789, in callback
    result_list.append(f.result())
  File "/usr/local/lib/python2.7/dist-packages/tornado/concurrent.py", line 232, in result
    raise_exc_info(self._exc_info)
  File "<string>", line 3, in raise_exc_info
HTTPError: HTTP 599: Timeout
ERROR:tornado.application:Multiple exceptions in yield list

1 个答案:

答案 0 :(得分:2)

您的程序递归要求Tornado同时保留10个以上的HTTP请求,但默认情况下,AsyncHTTPClient的max_clients为10。

当您开始第11次请求时,您的程序会死锁:它需要启动一个新的HTTP请求才能完成Fibonacci计算,但是在当前请求之一完成之前它无法启动新的请求。

如果添加以下行,您可以看到这一点:

import tornado.options
tornado.options.parse_command_line()

使用--logging=debug开始您的计划。最终您的程序会记录:

[D 160326 12:03:16 simple_httpclient:137] max_clients limit reached, request queued. 10 active, 11 queued requests.

......然后死锁。二十秒后,AsyncHTTPClient的默认超时会引发异常。

您可以通过在程序开头运行此程序来支持更高级别的递归:

AsyncHTTPClient.configure(None, max_clients=100)