Использование отложенных объектов внутри приложений Twisted - PullRequest
4 голосов
/ 24 октября 2011

Мне кажется, что я не понимаю некоторые вещи при написании приложений Twisted (файлы .tac).Использовать отложенные объекты в скриптах .py легко, просто вызвав reactor.run() в конце, но я не видел, чтобы reactor.run() использовался ни в одном из примеров кода приложения.

Может кто-нибудь объяснить:

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

1 Ответ

12 голосов
/ 25 октября 2011

1.Почему reactor.run() не вызывается в примерах .tac файлов?

.tac Файлы предназначены для загрузки с помощью инструмента командной строки "twistd", который запускает реактор для вас.

Запуск реактора - это то, что делается один раз, независимо от того, какой бит кода служит основным пунктом вашей программы.Большая часть кода Twisted фактически представляет собой плагин некоторого вида, предназначенный для работы в контексте более крупной системы.

В конкретном случае файлов .tac они никогда не должны запускаться как отдельныеодни только программы на Python: их задача - создать объект Application (с прикрепленной связкой объектов Service), который запускается при работе реактора.Важно, чтобы сам файл tac не выполнял много работы сам по себе, потому что (например) рассматриваемые реализации Service могут нуждаться в разделении кода, который должен запускаться как привилегированный и непривилегированный, что является сложным процессом;если работа выполняется в самом .tac, она может быть выполнена случайно как неправильный пользователь.

2.Как я могу использовать Deferred s внутри приложения Twisted без вызова reactor.run()?

Deferred - это просто механизм управления цепочками обратных вызовов.Вам не нужно звонить reactor.run(), или даже вообще иметь реактор, чтобы использовать их.Например:

>>> from twisted.internet.defer import Deferred
>>> d = Deferred()
>>> def hello(result):
...     print "'d' was fired:", result
...     return result + 3
... 
>>> d.addCallback(hello)
<Deferred at ...>
>>> print d
<Deferred at ...>
>>> d.callback(7)
'd' was fired: 7
>>> print d
<Deferred at ... current result: 10>

Тем не менее, многие API, которые возвращают Deferred, нуждаются в реакторе, чтобы выполнить некоторую работу, чтобы в конечном итоге вызвать .callback() на нем.Например, если вы сделаете ...

>>> from twisted.internet.task import deferLater
>>> from twisted.internet import reactor
>>> deferLater(reactor, 1.0, lambda: 20).addCallback(hello)
<Deferred at ...>
>>>

... вы будете сидеть без дела вечно, ожидая, пока это не произойдет, если кто-то не запустит реактор.Ничего не будет печататься, пока это не произойдет.

Но, если реактор уже работает - например, если вы запускали этот интерактивный пример в python -m twisted.conch.stdio, а не python, вы увидите, что Deferred получитперезвонил через секунду, потому что это интерактивное приглашение уже запускает реактор.

3.В чем различия между витыми сценариями и приложениями?

Это не формально разделенные термины.Любой скрипт Python может потенциально импортировать код из Twisted и использовать его любым способом, поэтому трудно сказать, что какое-либо конкретное свойство применимо к «скриптам», за исключением того, что они являются компьютерными программами: -).

Если поTwisted Application, вы имеете в виду файл или плагин .tac, разница в том, что этот вид кода разделяется на часть, которая создает сервис (код на верхнем уровне в вашем файле или плагине * 1045) и частьэто действительно делает работу (privilegedStartService / startService / stopService реализации сервисов, которые устанавливает указанный код верхнего уровня).Кроме того, код, который выполняется в этом контексте (то есть управляется twistd), не должен запускать сам реактор, поскольку он будет настроен и запущен самим twistd.Поэтому такой код должен также быть осторожным, чтобы избежать импорта twisted.internet.reactor, потому что twistd предоставляет возможность использовать различных реакторов (select, poll, epoll, kqueue и т. Д.)и импорт реактора до того, как twistd сможет его настроить, нарушит эту функцию.

...