[Twisted-Python] Twistd and application framework questions

Hello, I have finally gotten to a stage where I want to run my very large application as a daemonized twisted app, and I have two questions: 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. 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) 2) There are still scenarios where I would want to run my code the "reactor" way rather than than using the application framework, and I would love to be able to keep a single file that's compatible with both modes.. Is there a way to detect in runtime whether the code is being run through 'twistd' and the app framework or if its run directly? I was thinking of doing something like: if <test if we are run as an app>: internet.TCPServer(<port>,<factory>).setServiceParent(<myMultiservice>) else: reactor.listenTCP(<port>,<factory>) Thanks! Nadav

I can help you with this question:
2) There are still scenarios where I would want to run my code the "reactor" way rather than than using the application framework, and I would love to be able to keep a single file that's compatible with both modes.. Is there a way to detect in runtime whether the code is being run through 'twistd' and the app framework or if its run directly? I was thinking of doing something like:
I'm sure there's a way to introspect and figure out how you are being run. But... Why do you want to do this? If it's because you have different environments between prod and development then you can look at twisted plugins or I just use ENV vars from my os.environ. When the app starts it pulls os.environ vars. If it's to debug? You can twistd -noy. I'd also recommend that you are better off in the long run if you create a number of unittests. trial offers a way to run unittests within the reactor. If you haven't done this step it's a major lifesaver. Tests help you understand how your service,protocol,etc react and gives you confidence to roll all your services code together and have it just work. I've even used trial to do all kinds of crazy stuff in my normal non-twisted python coding. Also buildbot to automatically run the tests is handy. If it's to run just one service? You'd add this to the bottom of your service file (i'm assuming you've separated your service from your tac file) if __name__ == "__main__": #start your service/services here the tac file won't execute main when importing the service. So it's not two files. But I'm not sure what your end goal is here. Do tell. -rob

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.
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)
2) There are still scenarios where I would want to run my code the "reactor" way rather than than using the application framework, and I would love to be able to keep a single file that's compatible with both modes.. Is there a way to detect in runtime whether the code is being run through 'twistd' and the app framework or if its run directly? I was thinking of doing something like:
if <test if we are run as an app>: internet.TCPServer(<port>,<factory>).setServiceParent(<myMultiservice>) else:
1. You don't need to attach to parents service, you can also call start/stopService directly. 2. You can still call "self.port = reactor.listenTCP(...)" directly in a custom startService, and self.port.stopListening() in a custom stopService. You don't have to use twisted.application.internet, it doesn't add much beyond a little convenience. The point of services is to encapsulate startup and shutdown logic, not to make your life harder :)
participants (3)
-
Itamar Shtull-Trauring
-
Nadav Aharony
-
Rob Hoadley