slaprunner: Simplify process management and make sure 'process killer' handler works.

parent 5ec0a5a1
import atexit
import os import os
import psutil
import signal
import subprocess import subprocess
import sys
SLAPRUNNER_PROCESS_LIST = [] SLAPRUNNER_PROCESS_LIST = []
class Popen(subprocess.Popen): class Popen(subprocess.Popen):
""" """
Extension of Popen to launch and kill processes in a clean way Extension of Popen to launch and kill processes in a clean way
...@@ -21,55 +18,12 @@ class Popen(subprocess.Popen): ...@@ -21,55 +18,12 @@ class Popen(subprocess.Popen):
kwargs.setdefault('stdout', subprocess.PIPE) kwargs.setdefault('stdout', subprocess.PIPE)
kwargs.setdefault('close_fds', True) kwargs.setdefault('close_fds', True)
subprocess.Popen.__init__(self, *args, **kwargs) subprocess.Popen.__init__(self, *args, **kwargs)
global SLAPRUNNER_PROCESS_LIST
SLAPRUNNER_PROCESS_LIST.append(self) SLAPRUNNER_PROCESS_LIST.append(self)
self.stdin.flush() self.stdin.flush()
self.stdin.close() self.stdin.close()
self.stdin = None self.stdin = None
def kill(self, sig=signal.SIGTERM, recursive=False):
"""
Kill process and all its descendants if recursive
"""
if self.poll() is None:
if recursive:
childs_pids = pidppid(self.pid)
for pid in childs_pids:
killNoFail(pid, sig)
killNoFail(self.pid, sig)
if self.poll() is not None:
SLAPRUNNER_PROCESS_LIST.remove(self)
def __del__(self):
"""
Del function, try to kill process group
and process if its group does not exist
"""
for pid in (-self.pid, self.pid):
try:
os.kill(-self.pid, 15)
except OSError:
pass
subprocess.Popen.__del__(self)
def pidppid(pid, recursive=True):
"""
Return a list of all children of pid
"""
return [p.pid for p in psutil.Process(pid).get_children(recursive=recursive)]
def killNoFail(pid, sig):
"""
function to kill without failing. Return True if kill do not fail
"""
try:
os.kill(pid, sig)
return True
except OSError:
return False
def isRunning(name): def isRunning(name):
""" """
Return True if a process with this name is running Return True if a process with this name is running
...@@ -90,20 +44,25 @@ def killRunningProcess(name, recursive=False): ...@@ -90,20 +44,25 @@ def killRunningProcess(name, recursive=False):
process.kill(recursive=recursive) process.kill(recursive=recursive)
def handler(sig, frame): sigterm_handled = False
def handler(*args, **kwargs):
""" """
Signal handler to kill all processes Signal handler to kill all processes
""" """
pid = os.getpid() global sigterm_handled
os.kill(-pid, sig) if sigterm_handled:
sys.exit() return
sigterm_handled = True
for process in SLAPRUNNER_PROCESS_LIST:
try:
process.kill()
except OSError:
pass
def setHandler(sig_list=None): def setHandler(sig_list=None):
if sig_list is None: atexit.register(handler)
sig_list = [signal.SIGTERM]
for sig in sig_list:
signal.signal(sig, handler)
def isPidFileProcessRunning(pidfile): def isPidFileProcessRunning(pidfile):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment