ответ joefis в основном здравый, но держу пари, что некоторые примеры будут полезны. Во-первых, есть несколько способов запустить код сразу после запуска реактора.
Это довольно просто:
def f():
print "the reactor is running now"
reactor.callWhenRunning(f)
Другой способ - использовать синхронизированные события, хотя, вероятно, нет смысла делать это таким образом, вместо использования callWhenRunning
:
reactor.callLater(0, f)
Вы также можете использовать базовый API, который callWhenRunning
реализован в терминах:
reactor.addSystemEventTrigger('after', 'startup', f)
Вы также можете воспользоваться услугами. Это немного сложнее, поскольку включает использование twistd(1)
(или что-то еще, что подключит сервисную систему к реактору). Но вы можете написать такой класс:
from twisted.application.service import Service
class ThingDoer(Service):
def startService(self):
print "The reactor is running now."
А затем напишите файл .tac следующим образом:
from twisted.application.service import Application
from thatmodule import ThingDoer
application = Application("Do Things")
ThingDoer().setServiceParent(application)
И, наконец, вы можете запустить этот файл .tac, используя twistd(1)
:
$ twistd -ny thatfile.tac
Конечно, это говорит только о том, как сделать одну вещь после запуска реактора, а это не совсем то, что вы просите. Однако это та же идея - вы определяете какой-то обработчик события и просите получить событие, вызывая этот обработчик; когда это называется, вы можете делать вещи. Та же идея применима ко всему, что вы делаете с Конч.
Это можно увидеть в примерах Conch , например, в sshsimpleclient.py:
class CatChannel(channel.SSHChannel):
name = 'session'
def openFailed(self, reason):
print 'echo failed', reason
def channelOpen(self, ignoredData):
self.data = ''
d = self.conn.sendRequest(self, 'exec', common.NS('cat'), wantReply = 1)
d.addCallback(self._cbRequest)
def _cbRequest(self, ignored):
self.write('hello conch\n')
self.conn.sendEOF(self)
def dataReceived(self, data):
self.data += data
def closed(self):
print 'got data from cat: %s' % repr(self.data)
self.loseConnection()
reactor.stop()
В этом примере channelOpen
- это обработчик события, вызываемый при открытии нового канала. Отправляет запрос на сервер. Он возвращает Deferred
, к которому он присоединяет обратный вызов. Этот обратный вызов является обработчиком событий, который будет вызываться при успешном выполнении запроса (в этом случае, когда cat
было выполнено). _cbRequest
- это обратный вызов, который он присоединяет, и этот метод делает следующий шаг - записывает несколько байтов в канал и затем закрывает его. Затем есть обработчик события dataReceived
, который вызывается при получении байтов по каналу, и обработчик события closed
, вызываемый при закрытии канала.
Таким образом, вы можете увидеть здесь четыре разных обработчика событий, некоторые из которых запускают операции, которые в конечном итоге вызовут более поздний обработчик событий.
Итак, чтобы вернуться к вашему вопросу о выполнении одного за другим, если вы хотите открывать два канала cat, один за другим, то в обработчике события closed
можно открыть новый канал (вместо остановки реактора как в этом примере).