import signal
import subprocess
+__ALL__ = ('ProcessManager', 'manager', 'register', 'unregister', 'call',
+ 'start', 'stop', 'kill', 'get', 'has', 'sigchild_handler')
+
class ProcessInfo:
def __init__(self, name, command, callback=None, persist=False,
args=None, kw=None, max_errors=3):
self.signal = None
self.process = None
self.error_count = 0
- self.last_return = None
self.running = False
def start(self):
assert self.process is None
self.kill(signal.SIGTERM)
def kill(self, signum):
assert self.process is not None
- os.kill(pi.process.pid, signum)
+ os.kill(self.process.pid, signum)
self.signal = signum
def __repr__(self):
pid = None
def stop(self, name):
assert name in self.namemap
- self.namemap[name].stop(name)
+ self.namemap[name].stop()
+
+ def restart(self, name):
+ logging.debug(u'ProcessManager.restart(%s)', name)
+ if name in self.namemap:
+ self.namemap[name].stop()
+ self.namemap[name].wait()
+ self.namemap[name].restart()
+ else:
+ self.namemap[name].start()
def kill(self, name, signum):
assert name in self.namemap
self.namemap[name].kill(name, stop)
- def sigchild_handler(self, signum):
+ def sigchild_handler(self, signum, stack_frame=None):
try:
(pid, status) = os.waitpid(-1, os.WNOHANG)
except OSError, e:
- if e.errno is e.ECHILD:
+ if e.errno is errno.ECHILD:
return
raise
while pid:
if pid in self.pidmap:
p = self.pidmap[pid]
+ p.process.returncode = status
if p.callback is not None:
p.callback(self, p)
if p.dont_run or not p.persist or p.error_count >= p.max_errors:
return
raise
- def __getitem__(self, name):
+ def get(self, name):
if isinstance(name, basestring): # is a name
if name in self.namemap:
return self.namemap[name]
else: # is a pid
if name in self.pidmap:
return self.pidmap[name]
- return KeyError, name
+ raise KeyError, name
- def __contains__(self, name):
+ def has(self, name):
if isinstance(name, basestring): # is a name
if name in self.namemap:
return True
return True
return False
+ def __getitem__(self, name):
+ return self.get(name)
+
+ def __contains__(self, name):
+ return self.has(name)
+
+# Globals
+manager = ProcessManager()
+register = manager.register
+unregister = manager.unregister
+call = manager.call
+start = manager.start
+stop = manager.stop
+kill = manager.kill
+get = manager.get
+has = manager.has
+sigchild_handler = manager.sigchild_handler
+
if __name__ == '__main__':
sig = None
count = 0
- def sigchild_handler(signum, stacktrace):
+ def SIGCHLD_handler(signum, stacktrace):
global sig
sig = signum
print 'SIGCHLD', signum
pm.start('test2')
print 'died:', pi.name, pi.command
- procman = ProcessManager()
-
- procman.register('test-service', ('sleep', '2'), notify, True)
- procman.register('test2', ('sleep', '3'), notify, False)
+ register('test-service', ('sleep', '2'), notify, True)
+ register('test2', ('sleep', '3'), notify, False)
- signal.signal(signal.SIGCHLD, sigchild_handler)
+ signal.signal(signal.SIGCHLD, SIGCHLD_handler)
- procman.call('test', ('sleep', '5'), notify)
- procman.start('test-service')
+ call('test', ('sleep', '5'), notify)
+ start('test-service')
- print "Esperando...", [pi.name for pi in procman.namemap.values()]
- while procman.pidmap:
+ print "Esperando...", [pi.name for pi in manager.namemap.values()]
+ while manager.pidmap:
signal.pause()
if sig == signal.SIGCHLD:
sig = None
- procman.sigchild_handler(sig)
- print "Esperando...", [pi.name for pi in procman.namemap.values()]
+ sigchild_handler(sig)
+ print "Esperando...", [pi.name for pi in manager.namemap.values()]