[Twisted-Python] sigchld
I'm in the process of porting code from Twisted 8.1 to 10.1 which needed some custom signal handling code. Twisted 8.1's approach to signal handling was (as far as we could tell) too monolithic, so we chose "installSignalHandlers=False" and wrote our own signal handling code, installing reactor._handleSigchld so that spawnProcess would work. Of course, we have to change this now since #733 was fixed ( http://twistedmatrix.com/trac/ticket/733). IIUC, (and please correct if I don't) the SIGCHLD handler installation is performed by twisted.internet.posixbase.PosixReactorBase._handleSignals (the "if platformType == 'posix':" block). So, one option would be to run that code while still using "installSignalHandlers=False". I'm wondering if there's a better way. What if I were to let Twisted install signal handlers, but run my own signal handling code after the reactor starts (using callLater(0,...)) that installs "super" handlers which calls the Twisted handler along with any other handlers I want to run. I'd use signal.getsignal to get a reference to the Twisted handler(s). Might this work? Or, is there an obvious flaw? In particular, can I get the SIGCHLD handler using signal.getsignal, then call it via my "super" handler? I don't need to do any special handling of SIGCHLD, so I could just leave that signal handler alone. All thoughts appreciated. Thanks, Jason -- Jason Rennie Research Scientist, ITA Software 617-714-2645 http://www.itasoftware.com/
On 02:27 pm, jrennie@gmail.com wrote:
I'm in the process of porting code from Twisted 8.1 to 10.1 which needed some custom signal handling code. Twisted 8.1's approach to signal handling was (as far as we could tell) too monolithic, so we chose "installSignalHandlers=False" and wrote our own signal handling code, installing reactor._handleSigchld so that spawnProcess would work. Of course, we have to change this now since #733 was fixed ( http://twistedmatrix.com/trac/ticket/733).
IIUC, (and please correct if I don't) the SIGCHLD handler installation is performed by twisted.internet.posixbase.PosixReactorBase._handleSignals (the "if platformType == 'posix':" block). So, one option would be to run that code while still using "installSignalHandlers=False".
I'm wondering if there's a better way. What if I were to let Twisted install signal handlers, but run my own signal handling code after the reactor starts (using callLater(0,...)) that installs "super" handlers which calls the Twisted handler along with any other handlers I want to run. I'd use signal.getsignal to get a reference to the Twisted handler(s). Might this work? Or, is there an obvious flaw? In particular, can I get the SIGCHLD handler using signal.getsignal, then call it via my "super" handler? I don't need to do any special handling of SIGCHLD, so I could just leave that signal handler alone.
On Python 2.5 and earlier you won't be able to get Twisted's SIGCHLD handler using signal.getsignal. For other signal handlers, signal.getsignal should work fine. I also think it would be good for the reactor to not do so much with signals (aside from SIGCHLD), or provide a better public interface for controlling what it does. What sort of things do your signal handlers do? Jean-Paul
On Fri, Feb 11, 2011 at 10:01 AM, <exarkun@twistedmatrix.com> wrote:
On Python 2.5 and earlier you won't be able to get Twisted's SIGCHLD handler using signal.getsignal.
We're also moving to python 2.6 (the change is really Debian 5 to Debian 6). Should it would work in 2.6?
What sort of things do your signal handlers do?
IIRC, the main thing is to shut down the web server (cherrypy) we're running in parallel with twisted. We also have some disk-caching for stateful signals which needs to ensure the cache file is up-to-date. Cheers, Jason
On 03:59 pm, jrennie@gmail.com wrote:
On Fri, Feb 11, 2011 at 10:01 AM, <exarkun@twistedmatrix.com> wrote:
On Python 2.5 and earlier you won't be able to get Twisted's SIGCHLD handler using signal.getsignal.
We're also moving to python 2.6 (the change is really Debian 5 to Debian 6). Should it would work in 2.6?
I think so.
What sort of things do your signal handlers do?
IIRC, the main thing is to shut down the web server (cherrypy) we're running in parallel with twisted. We also have some disk-caching for stateful signals which needs to ensure the cache file is up-to-date.
For shutdown-type things, reactor.addSystemEventTrigger(phase, 'shutdown', f) might be better than getting into signal handlers (where phase is 'before', 'during', or 'after'). Jean-Paul
On Fri, Feb 11, 2011 at 11:55 AM, <exarkun@twistedmatrix.com> wrote:
For shutdown-type things, reactor.addSystemEventTrigger(phase, 'shutdown', f) might be better than getting into signal handlers (where phase is 'before', 'during', or 'after').
That might be a better way to go. Thanks for the tip. Jason -- Jason Rennie Research Scientist, ITA Software 617-714-2645 http://www.itasoftware.com/
On Feb 11, 2011, at 11:55 AM, exarkun@twistedmatrix.com wrote:
On 03:59 pm, jrennie@gmail.com wrote:
On Fri, Feb 11, 2011 at 10:01 AM, <exarkun@twistedmatrix.com> wrote:
On Python 2.5 and earlier you won't be able to get Twisted's SIGCHLD handler using signal.getsignal.
We're also moving to python 2.6 (the change is really Debian 5 to Debian 6). Should it would work in 2.6?
I think so.
What sort of things do your signal handlers do?
IIRC, the main thing is to shut down the web server (cherrypy) we're running in parallel with twisted. We also have some disk-caching for stateful signals which needs to ensure the cache file is up-to-date.
For shutdown-type things, reactor.addSystemEventTrigger(phase, 'shutdown', f) might be better than getting into signal handlers (where phase is 'before', 'during', or 'after').
There's already a system event trigger already hooked up to the reactor: your main service's stopService call. If your cherrypy webserver is wrapped up in an IService implementation in the service hierarchy constructed in your twistd plugin or tac file, you can just implement 'stopService' and not do any manual registration with event triggers. This is really a better way to go in general, as it's easier for other API consumers to deal with such an object than using the global broadcasting mechanism in the reactor. If you do want to manually add your own system event trigger, in most interesting cases you'll need to use the 'before' phase. During 'before', Deferreds returned by event triggers are respected (i.e. the reactor keeps running as long as they haven't fired). If you schedule one for 'during' or 'after', the event trigger really needs to do all of its work and complete it immediately (i.e. before returning).
Thanks for all the help. We're going with addSystemEventTrigger for now, but we'll keep twistd in mind for future work. Jason On Fri, Feb 11, 2011 at 1:51 PM, Glyph Lefkowitz <glyph@twistedmatrix.com>wrote:
On Feb 11, 2011, at 11:55 AM, exarkun@twistedmatrix.com wrote:
On 03:59 pm, jrennie@gmail.com wrote:
On Fri, Feb 11, 2011 at 10:01 AM, <exarkun@twistedmatrix.com> wrote:
On Python 2.5 and earlier you won't be able to get Twisted's SIGCHLD handler using signal.getsignal.
We're also moving to python 2.6 (the change is really Debian 5 to Debian 6). Should it would work in 2.6?
I think so.
What sort of things do your signal handlers do?
IIRC, the main thing is to shut down the web server (cherrypy) we're running in parallel with twisted. We also have some disk-caching for stateful signals which needs to ensure the cache file is up-to-date.
For shutdown-type things, reactor.addSystemEventTrigger(phase, 'shutdown', f) might be better than getting into signal handlers (where phase is 'before', 'during', or 'after').
There's already a system event trigger already hooked up to the reactor: your main service's stopService call. If your cherrypy webserver is wrapped up in an IService implementation in the service hierarchy constructed in your twistd plugin or tac file, you can just implement 'stopService' and not do any manual registration with event triggers. This is really a better way to go in general, as it's easier for other API consumers to deal with such an object than using the global broadcasting mechanism in the reactor.
If you do want to manually add your own system event trigger, in most interesting cases you'll need to use the 'before' phase. During 'before', Deferreds returned by event triggers are respected (i.e. the reactor keeps running as long as they haven't fired). If you schedule one for 'during' or 'after', the event trigger really needs to do all of its work and complete it immediately (i.e. before returning).
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
-- Jason Rennie Research Scientist, ITA Software 617-714-2645 http://www.itasoftware.com/
participants (3)
-
exarkun@twistedmatrix.com
-
Glyph Lefkowitz
-
Jason Rennie