来自口译员会议:
>>>io_loop.call_later(comments_page_delay, functools.partial(http_client.fetch, "google.com", lambda x: print('kek')))
<tornado.ioloop._Timeout object at 0x7fe9a2427b08>
>>> io_loop.start()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.6/site-packages/tornado/ioloop.py", line 755, in start
raise RuntimeError("IOLoop is already running")
RuntimeError: IOLoop is already running
>>> io_loop.call_later(comments_page_delay, functools.partial(http_client.fetch, "google.com", lambda x: print('kek')))
<tornado.ioloop._Timeout object at 0x7fe9a0267808>
>>> io_loop.stop()
>>> io_loop.start()
>>> io_loop.start()
kek
kek
kek
下面:
io_loop = tornado.ioloop.IOLoop.current()
comments_page_delay = 0.1
编辑:
AsyncHTTPClient.configure("tornado.curl_httpclient.CurlAsyncHTTPClient")
http_client = AsyncHTTPClient()
http_client.max_clients = max_clients
http_client.request_timeout = request_timeout
问题:
ioloop似乎没有运行call_later添加的呼叫。它正在运行,正如我尝试执行io_loop.start()时的错误所证明的那样。为了让它实际执行,我必须首先停止循环,然后启动它两次 ...非常混乱。
我承认自从我使用Tornado以来已经有一段时间了,但这基本上等同于我所知道的其他代码。
编辑:代码在第一次运行时正常运行,但在连续运行时无效。此时需要运行io_loop.start()两次返回
这里是完整的代码(略有删失):
"""...docstring..."""
import functools
import tornado
from tornado.httpclient import AsyncHTTPClient
from lxml import html as lh
from config import comments_page_delay, max_clients, request_timeout
from debug import log
AsyncHTTPClient.configure("tornado.curl_httpclient.CurlAsyncHTTPClient")
http_client = AsyncHTTPClient()
http_client.max_clients = max_clients
http_client.request_timeout = request_timeout
io_loop = tornado.ioloop.IOLoop.current()
def x(y, proxy):
"""...docstring..."""
def handle_response(response):
if response.error:
log('...message...'
.format(uid, response.error), 1)
else:
print('Worked')
data = response.body
comments_url = "...valid url..."
io_loop.call_later(comments_page_delay, functools.partial(http_client.fetch, comments_url, handle_response,
proxy_host=proxy['host'], proxy_port=proxy['port']))
x(1, {'host': None, 'port': None})
io_loop.start()
print('ok')
io_loop.stop()
我在Emacs python解释器会话中运行代码,如果这在某种程度上是相关的。我会在一秒钟内尝试正常的python会话。
EDIT2 :如果我在普通的python解释器中运行该代码会发生什么:
$ python -i fetch.py
Worked
Traceback (most recent call last):
File "fetch.py", line 34, in <module>
io_loop.start()
File "/usr/lib/python3.6/site-packages/tornado/ioloop.py", line 863, in start
event_pairs = self._impl.poll(poll_timeout)
KeyboardInterrupt
>>> >>> >>> get_user_profile_link(1, {'host': None, 'port': None})
>>>
>>>
>>> io_loop.start()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.6/site-packages/tornado/ioloop.py", line 755, in start
raise RuntimeError("IOLoop is already running")
RuntimeError: IOLoop is already running
>>> io_loop.stop()
>>> io_loop.start()
>>> io_loop.start()
Worked
看来io_loop.start()阻塞了吗?我没想到,这可能是问题所在。我现在必须重新思考整个程序的架构。
答案 0 :(得分:0)
未捕获的异常(在这种情况下为KeyboardInterrupt
)使IOLoop
处于未定义状态。在发生此类异常后,无法重新启动IOLoop
(因为它可能在任何时候出现并使IOLoop
的内部结构不一致)。一般来说,它假设该过程将在KeyboardInterrupt
之后退出。可以创建新的IOLoop
并重新开始使用它,但是您必须小心重新创建依赖于它的所有对象。
不幸的是,这意味着将Tornado与交互式解释器一起使用实际上很困难。我开发Tornado应用程序的常用工作流程是使用python -m tornado.autoreload
运行脚本,并在编辑脚本时让脚本从头开始重新运行。