
On Wed, Nov 27, 2013, at 19:20, exarkun@twistedmatrix.com wrote: ...
What about something like this instead?
@implementer(IService) class Runner(object): ... @classmethod def loadFromWhatever(cls, name): return deferLater(reactor, Runner, name)
def __init__(self, name): self.name = name
def startService(self): self.running = True print 'realStartService', self.name, reactor.running
def parent(service): application.setServiceParent(service)
A small detail: should this be service.setServiceParent(application)? Peter.
loading = Runner.initializeFromWhatever("foo") loading.addCallback(parent) loading.addCallback(lambda ignored: Runner.initializeFromWhatever("bar")) loading.addCallback(parent) loading.addErrback(stopTheReactorOrWhatever)
The advantage I see of this approach is that a `Runner` never exists in the service hierarchy until it is fully initialized, started, and running.
If a `Runner` is only partially ready and the process shuts down then its `stopService` method isn't called because it's not part of the service hierarchy.
I could definitely imagine a library to help with this kind of thing. For example, perhaps you want the above encapsulated as:
asynchronouslySetUpServices(application, [ lambda: Runner.initializeFromWhatever("foo"), lambda: Runner.initialifrFromWhatever("bar")])
And maybe then you want to add in some logic so that if the application gets shut down while some things are still being initialized then you cancel their Deferred. Then you have good cleanup support for the uninitialized case - without complicating `stopService` (the cleanup logic is isolated in the implementation of Deferred cancellation where it belongs - eg, with this `deferLater`-based asynchronousness it's alreay present since deferLater implements cancellation already).
Jean-Paul
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python