Выполнять асинхронный код в Twisted *перед* запуском сервиса

Я начинаю свое искривленное приложение с:

application = twisted.application.service.Application('myserv')
my_service = MyService()
my_service.setServiceParent(application)
my_factory = twisted.internet.protocol.ServerFactory()
my_factory.protocol = MyProtocol
twisted.application.internet.TCPServer(port, my_factory).setServiceParent(application)

class MyService:
    def startService(self):
        #only synchronous code here?

Прежде чем эта служба сможет принимать клиентские tcp-соединения, мне нужно установить соединение с сервером Redis, что включает выполнение асинхронного кода. Я хочу использовать d=txredisapi.Connection() или, альтернативно, d = yield txredisapi.Connection() с inlineCallbacks . Этот отложенный должен срабатывать до того, как служба сможет запуститься (до того, как клиентские TCP-соединения будут приняты). Где лучше всего начать txredisapi.Connection()? В идеале я хочу поместить его в класс MyService.


person mercador    schedule 25.04.2013    source источник
comment
связанные: Зависимость и взаимодействие служб в Twisted Python   -  person jfs    schedule 25.04.2013


Ответы (1)


Просто напишите функцию на верхнем уровне, которая создает соединение с Redis и передает его в MyService. Службы могут быть добавлены в асинхронном коде.

application = twisted.application.service.Application("myserv")

@defer.inlineCallbacks
def startApp():
  rc = yeld txredisapi.Connection()
  my_service = MyService(rc)
  my_service.setServiceParent(application)
  my_factory = twisted.internet.protocol.ServerFactory()
  my_factory.protocol = MyProtocol
  twisted.application.internet.TCPServer(port, my_factory).setServiceParent(application)

startApp()
person monoid    schedule 25.04.2013
comment
Есть ли способ настроить соединение Redis в классе MyService? Я надеялся, что что-то вроде addSystemEventTrigger('before','startup'...) может сработать? - person mercador; 25.04.2013
comment
Вы не можете установить его в конструкторе с помощью inlineCallbacks (конструкторы AFAIK не работают с inlineCallbacks, но вы можете попробовать). Но вы можете сохранить Redis Deferred в конструкторе MyService, а затем вызвать my_service.setServiceParent(application) в обратном вызове deferred. Вы можете написать для него метод, передав application в качестве аргумента. - person monoid; 25.04.2013