В случае, если это не очевидно, это называется реактор, потому что он реагирует на вещи. Цикл как реагирует.
Одна линия на время:
while True:
Это не фактическиwhile True
; это больше похоже на while not loop.stopped
. Вы можете позвонить reactor.stop()
, чтобы остановить цикл, и (после выполнения некоторой логики отключения) цикл будет фактически завершен. Но это изображается в примере как while True
, потому что, когда вы пишете долгоживущую программу (как часто вы с Twisted), лучше предположить, что ваша программа будет либо сбой или запуск навсегда, и что «чистое выход» не действительно вариант.
timeout = time_until_next_timed_event()
Если бы мы должны были расширить этот расчет немного, это может сделать больше смысла:
def time_until_next_timed_event():
now = time.time()
timed_events.sort(key=lambda event: event.desired_time)
soonest_event = timed_events[0]
return soonest_event.desired_time - now
timed_events
список мероприятий, запланированных с reactor.callLater
; то есть функции, которые приложение попросило Twisted для запуска в определенное время.
events = wait_for_events(timeout)
Эта линия представляет собой «магическую» часть витой пары. Я не могу расширить wait_for_events
в общем виде, потому что его реализация зависит от того, как операционная система делает нужные события доступными. И, учитывая, что операционные системы являются сложными и хитрыми зверями, я не могу расширять его определенным образом, сохраняя при этом достаточно простым для ответа на ваш вопрос.
Эта функция предназначена для обозначения того, спросите операционную систему или оболочку Python вокруг нее блокировать до тех пор, пока один или несколько объектов, ранее зарегистрированных с ней, - как минимум, такие, как порты прослушивания и установленные соединения, но также, возможно, такие вещи, как кнопки, на которые можно щелкнуть - «готов к работе». Работа может считывать некоторые байты из сокета, когда они поступают из сети. Работа может записывать байты в сеть, когда буфер опустошается достаточно для этого. Это может быть прием нового соединения или использование закрытого. Каждое из этих возможных событий - это функции, которые реактор может потребовать от ваших объектов: dataReceived
, buildProtocol
, resumeProducing
и т. Д., Что вы узнаете, пройдете ли вы полный учебник Twisted.
После того, как у нас есть список гипотетических объектов «события», каждый из которых имеет воображаемый метод «process
» (точные названия методов в реакторе отличаются только из-за несчастных случаев истории), мы тогда вернуться к работе со временем:
events += timed_events_until(now())
Во-первых, это предполагает, events
просто list
абстрактного Event
класса, который имеет process
метод, что каждый конкретный тип события, необходимо заполнить.
На этом этапе цикл «проснулся», потому что wait_for_events
, остановил блокировку. Тем не менее, мы не знаем, сколько запланированных событий мы могли бы выполнить на основе , как долго он «заснул» для. Возможно, мы спали за полный тайм-аут, если ничего не было, но если бы было много соединений, мы могли бы спать практически без времени. Поэтому мы проверяем текущее время («now()
»), и мы добавляем в список событий, которые нам нужно обработать, каждое событие с таймером с desired_time
, которое находится в или до настоящего времени.
Наконец,
for event in events:
event.process()
Это просто означает, что Twisted просматривает список вещей, которые он должен делать, и делает их. В действительности, конечно, он обрабатывает исключения вокруг каждого события, и конкретная реализация реактора часто просто обращается прямо к обработчику событий, а не создает объект, похожий на Event
, для записи работы, которая должна быть выполнена в первую очередь, но концептуально это просто что происходит. event.process
здесь может означать вызов socket.recv()
, а затем yourProtocol.dataReceived
с результатом, например.
Надеюсь, что это расширенное объяснение поможет вам обвести вокруг себя голову. Если вы хотите узнать больше о Twisted, работая над этим, я бы посоветовал вам join the mailing list, перескочить на канал IRC, #twisted
, чтобы поговорить о приложениях или #twisted-dev
, чтобы работать на самом скрученном, как на Freenode.