Following up on myself.... Here's an updated/working version of the MultiService subclass I proposed the other day:
def __init__(self, guardService): service.MultiService.__init__(self) self.guardService = guardService self.startDeferred = defer.Deferred() self.stopDeferred = defer.Deferred()
def startService(self): def startOthers(_): log.msg("Guard service startup succeeded. Starting other services.") service.MultiService.startService(self) def initFailed(f): log.msg("Guard service startup failed.") return f d = defer.maybeDeferred(self.guardService.startService) d.addCallbacks(startOthers, initFailed) d.chainDeferred(self.startDeferred)
def stopService(self): d = service.MultiService.stopService(self) d.addCallback(lambda _: self.guardService.stopService()) d.chainDeferred(self.stopDeferred) return self.stopDeferred
This is pretty much as I described earlier.
I've added self.startDeferred and self.stopDeferred deferreds. These give the programmer using this class (who, I imagine, is probably doing so in the context of writing a Twistd plugin - i.e., writing the makeService method in a class implementing IServiceMaker and IPlugin) the chance to add callbacks to the chain of events that happen when the service is started and stopped. Their use is optional.
It's easy to see how to make guardService default to None, which would make it possible to merge the above into MultiService itself.
If there's any interest at all in this, I'm happy to open a ticket, run tests, submit a patch, etc.