Twisted Reactor не может быть перезапущен - используется асинхронная многопоточность

У меня есть список URL-адресов. Я хочу получать их содержимое асинхронно каждые 10 секунд.

urls = [
 'http://www.python.org', 
 'http://stackru.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()

Как мне это сделать? Этот код позволяет мне получать содержимое URL только один раз. Призывая это снова бросает error.ReactorNotRestartable()

Спасибо:)

1 ответ

Это определенно возможно с Twisted.

Во-первых, хотя это не связано с вашим вопросом, не используйте getPage, Это очень ограниченный API с плохими настройками по умолчанию для безопасности по HTTPS. Вместо этого используйте Treq.

Теперь на ваш главный вопрос.

Важная вещь, чтобы понять о reactor.run() в том, что это не значит "запустить этот код здесь". Это означает "запустить всю программу". когда reactor.run() выходит, пришло время для вашей программы, чтобы выйти.

К счастью для вас, в Twisted есть хороший встроенный способ делать вещи по регулярному расписанию: LoopingCall,

Вот рабочий пример, используя treq а также LoopingCall:

urls = [
    'http://www.python.org',
    'http://stackru.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 секунд и будет реагировать разумно, вместо того, чтобы слишком много невыполненных запросов накапливалось, или задерживаться дольше и дольше, поскольку запросы занимают больше времени.

Другие вопросы по тегам