Merge pull request #922 from smaarn/fix/747/improve-termination-signal-handling

[Python 3 only] Changed SIGTERM signal handling.
pull/929/head
morpheus65535 5 years ago committed by GitHub
commit dc09fe21b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -55,34 +55,6 @@ class DaemonStatus(ProcessRegistry):
def unregister(self, process): def unregister(self, process):
self.__processes.remove(process) self.__processes.remove(process)
@staticmethod
def __wait_for_processes(processes, timeout):
"""
Waits all the provided processes for the specified amount of time in seconds.
"""
reference_ts = time.time()
elapsed = 0
remaining_processes = list(processes)
while elapsed < timeout and len(remaining_processes) > 0:
remaining_time = timeout - elapsed
for ep in list(remaining_processes):
if ep.poll() is not None:
remaining_processes.remove(ep)
else:
if remaining_time > 0:
if PY3:
try:
ep.wait(remaining_time)
remaining_processes.remove(ep)
except subprocess.TimeoutExpired:
pass
else:
# In python 2 there is no such thing as some mechanism to wait with a timeout
time.sleep(1)
elapsed = time.time() - reference_ts
remaining_time = timeout - elapsed
return remaining_processes
@staticmethod @staticmethod
def __send_signal(processes, signal_no, live_processes=None): def __send_signal(processes, signal_no, live_processes=None):
""" """
@ -105,9 +77,11 @@ class DaemonStatus(ProcessRegistry):
Flags this instance as should stop and terminates as smoothly as possible children processes. Flags this instance as should stop and terminates as smoothly as possible children processes.
""" """
self.__should_stop = True self.__should_stop = True
live_processes = DaemonStatus.__send_signal(self.__processes, signal.SIGINT, list()) DaemonStatus.__send_signal(self.__processes, signal.SIGINT, list())
live_processes = DaemonStatus.__wait_for_processes(live_processes, 120)
DaemonStatus.__send_signal(live_processes, signal.SIGTERM) def force_stop(self):
self.__should_stop = True
DaemonStatus.__send_signal(self.__processes, signal.SIGTERM)
def should_stop(self): def should_stop(self):
return self.__should_stop return self.__should_stop
@ -170,11 +144,19 @@ if __name__ == '__main__':
if PY3: if PY3:
daemonStatus = DaemonStatus() daemonStatus = DaemonStatus()
def force_shutdown():
# force the killing of children processes
daemonStatus.force_stop()
# if a new SIGTERM signal is caught the standard behaviour should be followed
signal.signal(signal.SIGTERM, signal.SIG_DFL)
# emulate a Ctrl C command on itself (bypasses the signal thing but, then, emulates the "Ctrl+C break")
os.kill(os.getpid(), signal.SIGINT)
def shutdown(): def shutdown():
# indicates that everything should stop # indicates that everything should stop
daemonStatus.stop() daemonStatus.stop()
# emulate a Ctrl C command on itself (bypasses the signal thing but, then, emulates the "Ctrl+C break") # if a new sigterm signal is caught it should force the shutdown of children processes
os.kill(os.getpid(), signal.SIGINT) signal.signal(signal.SIGTERM, lambda signal_no, frame: force_shutdown())
signal.signal(signal.SIGTERM, lambda signal_no, frame: shutdown()) signal.signal(signal.SIGTERM, lambda signal_no, frame: shutdown())

Loading…
Cancel
Save