From 3c996c366af2730833c663b4490ffc7854cacbfe 2011-06-20 23:40:20 From: MinRK Date: 2011-06-20 23:40:20 Subject: [PATCH] scrub twisted/deferred references from launchers also extract daemonize function from twisted.scripts._twistd_unix --- diff --git a/IPython/parallel/apps/ipclusterapp.py b/IPython/parallel/apps/ipclusterapp.py index 4b59516..efb3652 100755 --- a/IPython/parallel/apps/ipclusterapp.py +++ b/IPython/parallel/apps/ipclusterapp.py @@ -34,6 +34,7 @@ from zmq.eventloop import ioloop from IPython.config.application import Application, boolean_flag from IPython.config.loader import Config from IPython.core.newapplication import BaseIPythonApplication, ProfileDir +from IPython.utils.daemonize import daemonize from IPython.utils.importstring import import_item from IPython.utils.traitlets import Int, Unicode, Bool, CFloat, Dict, List @@ -368,7 +369,6 @@ class IPClusterEngines(BaseParallelApplication): # TODO: Get daemonize working on Windows or as a Windows Server. if self.daemonize: if os.name=='posix': - from twisted.scripts._twistd_unix import daemonize daemonize() dc = ioloop.DelayedCallback(self.start_engines, 0, self.loop) @@ -468,7 +468,6 @@ class IPClusterStart(IPClusterEngines): # TODO: Get daemonize working on Windows or as a Windows Server. if self.daemonize: if os.name=='posix': - from twisted.scripts._twistd_unix import daemonize daemonize() dc = ioloop.DelayedCallback(self.start_controller, 0, self.loop) diff --git a/IPython/parallel/apps/launcher.py b/IPython/parallel/apps/launcher.py index 3f63b1a..285c349 100644 --- a/IPython/parallel/apps/launcher.py +++ b/IPython/parallel/apps/launcher.py @@ -157,29 +157,20 @@ class BaseLauncher(LoggingConfigurable): return False def start(self): - """Start the process. - - This must return a deferred that fires with information about the - process starting (like a pid, job id, etc.). - """ + """Start the process.""" raise NotImplementedError('start must be implemented in a subclass') def stop(self): """Stop the process and notify observers of stopping. - This must return a deferred that fires with information about the - processing stopping, like errors that occur while the process is - attempting to be shut down. This deferred won't fire when the process - actually stops. To observe the actual process stopping, see - :func:`observe_stop`. + This method will return None immediately. + To observe the actual process stopping, see :meth:`on_stop`. """ raise NotImplementedError('stop must be implemented in a subclass') def on_stop(self, f): - """Get a deferred that will fire when the process stops. - - The deferred will fire with data that contains information about - the exit status of the process. + """Register a callback to be called with this Launcher's stop_data + when the process actually finishes. """ if self.state=='after': return f(self.stop_data) @@ -202,7 +193,7 @@ class BaseLauncher(LoggingConfigurable): """Call this to trigger process stop actions. This logs the process stopping and sets the state to 'after'. Call - this to trigger all the deferreds from :func:`observe_stop`.""" + this to trigger callbacks registered via :meth:`on_stop`.""" self.log.info('Process %r stopped: %r' % (self.args[0], data)) self.stop_data = data @@ -215,8 +206,6 @@ class BaseLauncher(LoggingConfigurable): def signal(self, sig): """Signal the process. - Return a semi-meaningless deferred after signaling the process. - Parameters ---------- sig : str or int @@ -247,7 +236,6 @@ class LocalProcessLauncher(BaseLauncher): work_dir=work_dir, config=config, **kwargs ) self.process = None - self.start_deferred = None self.poller = None def find_args(self): @@ -520,7 +508,7 @@ class MPIExecEngineSetLauncher(MPIExecLauncher): # SSH launchers #----------------------------------------------------------------------------- -# TODO: Get SSH Launcher working again. +# TODO: Get SSH Launcher back to level of sshx in 0.10.2 class SSHLauncher(LocalProcessLauncher): """A minimal launcher for ssh. @@ -700,7 +688,7 @@ class WindowsHPCLauncher(BaseLauncher): '/scheduler:%s' % self.scheduler ] self.log.info("Starting Win HPC Job: %s" % (self.job_cmd + ' ' + ' '.join(args),)) - # Twisted will raise DeprecationWarnings if we try to pass unicode to this + output = check_output([self.job_cmd]+args, env=os.environ, cwd=self.work_dir, @@ -1072,3 +1060,4 @@ sge_launchers = [ ] all_launchers = local_launchers + mpi_launchers + ssh_launchers + winhpc_launchers\ + pbs_launchers + sge_launchers + diff --git a/IPython/utils/daemonize.py b/IPython/utils/daemonize.py new file mode 100644 index 0000000..1c6d02d --- /dev/null +++ b/IPython/utils/daemonize.py @@ -0,0 +1,26 @@ +"""daemonize function from twisted.scripts._twistd_unix.""" + +#----------------------------------------------------------------------------- +# Copyright (c) Twisted Matrix Laboratories. +# See Twisted's LICENSE for details. +# http://twistedmatrix.com/ +#----------------------------------------------------------------------------- + +import os, errno + +def daemonize(): + # See http://www.erlenstar.demon.co.uk/unix/faq_toc.html#TOC16 + if os.fork(): # launch child and... + os._exit(0) # kill off parent + os.setsid() + if os.fork(): # launch child and... + os._exit(0) # kill off parent again. + null = os.open('/dev/null', os.O_RDWR) + for i in range(3): + try: + os.dup2(null, i) + except OSError, e: + if e.errno != errno.EBADF: + raise + os.close(null) +