Python Twisted tap插件,多服务,启动时需要一些回调

Python Twisted tap插件,多服务,启动时需要一些回调,python,twisted,Python,Twisted,使用下面的源代码示例,makeService()启动两个服务: AMQP代理:启动TCP客户端以连接到AMQP代理 HTTPApi:启动twisted.web.resource.resourceTCPServer 启动时,第二个(HTTPApi)需要到AMQP代理的就绪/可用连接,否则,HTTPApi将无法启动 我正在寻找一种干净的方法,如何在AMQP代理就绪时回调HTTPApistartHTTPApiService(),作为信息,我已经在连接就绪时触发了一个延迟:self.components

使用下面的源代码示例,makeService()启动两个服务:

  • AMQP代理:启动TCP客户端以连接到AMQP代理
  • HTTPApi:启动twisted.web.resource.resourceTCPServer
  • 启动时,第二个(HTTPApi)需要到AMQP代理的就绪/可用连接,否则,HTTPApi将无法启动

    我正在寻找一种干净的方法,如何在AMQP代理就绪时回调HTTPApistartHTTPApiService(),作为信息,我已经在连接就绪时触发了一个延迟:self.components['AMQP-Broker-factory'].getChannelReadyFerred(),但是如何在makeService()中使用它呢

    源代码:

    from zope.interface import implements
    from twisted.python import usage
    from twisted.plugin import IPlugin
    from twisted.application import internet, service
    from twisted.web import server
    from nimsaj.queues.factory import AmqpFactory
    from nimsaj.protocols.http.server import HTTPApi
    
    class nimsajServiceMaker:
    
        implements(service.IServiceMaker, IPlugin)
    
        tapname = "nimsaj"
        description = "Network IMS-AJ"
        options = usage.Options
        top_service = None
        components = {}
    
        def startAMQPBrokerService(self):
            "Start AMQP Broker"
    
            self.components['amqp-broker-factory'] = AmqpFactory()
    
            # Add service
            AMQPBrokerService = internet.TCPClient('127.0.0.1', 
                                                   5672, 
                                                   self.components['amqp-broker-factory'])
            AMQPBrokerService.setServiceParent(self.top_service)
    
        def startHTTPApiService(self):
            "Start HTTP Api"
    
            httpApi_f = HTTPApi(self.components['amqp-broker-factory'])
    
            httpApi = internet.TCPServer(80, 
                                         server.Site(httpApi_f), 
                                         interface = '0.0.0.0'
                                         )
            httpApi.setServiceParent(self.top_service)
    
        def makeService(self, options):
            self.top_service = service.MultiService()
            self.options = options
    
            ########################################################
            # Start AMQP Broker
            self.startAMQPBrokerService()
    
            ########################################################
            # Start HTTP Api
            self.startHTTPApiService()
    
            return self.top_service
    
    service_maker = nimsajServiceMaker()
    

    我是这样做的,我不知道在你的情况下这是否足够。在我的情况下,我只是确保在数据库准备就绪之前,应用程序上没有设置数据存储服务(因此不会响应请求)。如果有更好的方法来处理服务依赖性,我也想知道

    def setServiceParentWhenDepReady(constraint, service, parent):
        if constraint.running:
            service.setServiceParent(parent)
        else:
            reactor.callLater(0.1, setServiceParentWhenDepReady,
                              *(constraint, service, parent))
    
    
    def application(config):
        app = Application('appName')
    
        srv_resolver = SrvResolver()
        app.setComponent(ISrvResolver, srv_resolver)
    
        postgresservice = PostgresService(app, config)
        postgresservice.setServiceParent(app)
        datastoreservice = RpcService(app, config)
        setServiceParentWhenDepReady(postgresservice, datastoreservice, app)
    
        return app
    

    这是一个很好的解决方案,但不能被认为是正确的答案,我正在寻找最佳实践和最干净的方法来正确处理问题,在您的示例中,我可以看到没有错误处理:如果constraint.running无法实现会发生什么?是的,那么它将永远循环..:(您可以在
    setServiceParentWhenDepReady(*args,maxretry=100)中添加计数器)
    类似的内容在尝试
    x
    后会引发错误…但可能存在更干净的解决方案。如果您找到一个好的干净解决方案,请将其发布在此处。您看到了吗,。可能会给出一些见解。但归结起来是同一件事。在对延迟服务的回调中使用
    setServiceParent