Twisted Reactor不可重新启动 - 重复使用异步线程

时间:2015-10-05 22:15:40

标签: multithreading twisted reactor

我有一个网址列表。我希望每隔10秒异步获取一次内容。

urls = [
 'http://www.python.org', 
 'http://stackoverflow.com', 
 'http://www.twistedmatrix.com', 
 'http://www.google.com',
 'http://launchpad.net',
 'http://github.com',
 'http://bitbucket.org',
]

waiting = [client.getPage(url) for url in urls]
defer.gatherResults(waiting).addCallback(saveResults)

reactor.run()

我该怎么做?此代码允许我只获取一次网址内容。再次调用它会抛出error.ReactorNotRestartable()

谢谢:)

1 个答案:

答案 0 :(得分:2)

使用Twisted绝对可以。

首先,虽然这与您的问题有些不相关,但请勿使用getPage。它是一个非常有限的API,HTTPS上的安全性默认设置很差。相反,请使用Treq

现在,关于你的主要问题。

了解reactor.run()的重要一点是,它并不代表"在这里运行此代码"。这意味着"运行整个程序"。当reactor.run()退出时,您的程序将退出该时间。

幸运的是,Twisted有一个很好的内置方式来定期做事:LoopingCall

以下是一个使用treqLoopingCall的工作示例:

urls = [
    'http://www.python.org',
    'http://stackoverflow.com',
    'http://www.twistedmatrix.com',
    'http://www.google.com',
    'http://launchpad.net',
    'http://github.com',
    'http://bitbucket.org',
]

from twisted.internet.task import LoopingCall
from twisted.internet.defer import gatherResults
from treq import get, content

def fetchWebPages():
    return (gatherResults([get(url).addCallback(content) for url in urls])
            .addCallback(saveResults))

def saveResults(responses):
    print("total: {} bytes"
          .format(sum(len(response) for response in responses)))


repeatedly = LoopingCall(fetchWebPages)
repeatedly.start(10.0)

from twisted.internet import reactor
reactor.run()

作为奖励,它处理fetchWebPages花费超过10秒的情况,并且会智能地做出反应,而不是让太多未完成的请求堆积起来,或者随着请求需要更长时间而延迟更长时间。