[Twisted-Python] Twistd and application framework questions

Terry Jones terry at jon.es
Thu Apr 2 12:29:47 EDT 2009

Hi Nadav, Itamar

>>>>> "Itamar" == Itamar Shtull-Trauring <itamar at itamarst.org> writes:
Itamar> On Wed, 2009-04-01 at 13:16 -0400, Nadav Aharony wrote:

>> 1) The program uses multiple UDP/TCP clients and servers that are
>> currently launched with reactor.listenTCP / UDP connectTCP/UDP etc. I've
>> been using MultiService, according to the twisted documentation.  Some
>> of these services were are at a top level of my app so it was easy to
>> turn that part into a .tac file and switch the reacor calls to
>> internet.TCPServer etc.  However, some of them are deep inside my code,
>> and are instantiated on the fly.

We (at Fluidinfo) have a similar situation, though I wouldn't say the
services that start/stop later are deeply buried. They're just not started
right away when startService is called on the MultiService via the plugin

>> What is the "right" way to attach them to my service parent? (the part
>> with ".setServiceParent(<myMultiservice>") Should I now add a pointer to
>> my MultiService that will be propagated down the code hierarchy to each
>> of these calls and be accessible at the inner scopes?  Is there a neater
>> way to do it just with importing the right modules?  (in the same way
>> that in usual twisted scripts the loaded reactor is a global reactor)

At the suggestion/insistence :-) of Esteve Fernandez, we do this by using
the components machinery of Twisted. You write an adaptor that knows how to
take the core of your service and adapt it to some other form of service
interface. The adaptor can have access to the original Multiservice, it can
provide startService and stopService methods that call into the special
service that you're trying to launch, etc.  It's nice because the
mechanisms for creating a new service and getting it hooked up to the
outside world, can be encapsulated in the adaptor and don't pollute the
code that's trying to just provide the underlying service (your "business
logic" I guess you'd call that :-))

BTW, we also have some service startup ordering constraints that we fixed
by subclassing Multiservice. There's a slow-motion thread on this approach,
so the jury's still out, but the code described here works fine for me:


Itamar> 1. You don't need to attach to parents service, you can also call
Itamar> start/stopService directly.

Itamar> 2. You can still call "self.port = reactor.listenTCP(...)" directly
Itamar> in a custom startService, and self.port.stopListening() in a custom
Itamar> stopService. You don't have to use twisted.application.internet, it
Itamar> doesn't add much beyond a little convenience.

Itamar> The point of services is to encapsulate startup and shutdown logic,
Itamar> not to make your life harder :)

The main reason I like to add the new service to the original Multiservice
is that its stopService gets called at the right time and I don't have to
think about it. That's a nice convenience.


More information about the Twisted-Python mailing list