@ -55,34 +55,6 @@ class DaemonStatus(ProcessRegistry):
def unregister ( self , 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
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 .
"""
self . __should_stop = True
live_processes = DaemonStatus . __send_signal ( self . __processes , signal . SIGINT , list ( ) )
live_processes = DaemonStatus . __wait_for_processes ( live_processes , 120 )
DaemonStatus . __send_signal ( live_processes , signal . SIGTERM )
DaemonStatus . __send_signal ( self . __processes , signal . SIGINT , list ( ) )
def force_stop ( self ) :
self . __should_stop = True
DaemonStatus . __send_signal ( self . __processes , signal . SIGTERM )
def should_stop ( self ) :
return self . __should_stop
@ -170,11 +144,19 @@ if __name__ == '__main__':
if PY3 :
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 ( ) :
# indicates that everything should stop
daemonStatus . stop ( )
# emulate a Ctrl C command on itself (bypasses the signal thing but, then, emulates the "Ctrl+C break")
os . kill ( os . getpid ( ) , signal . SIGINT )
# if a new sigterm signal is caught it should force the shutdown of children processes
signal. signal ( signal . SIGTERM , lambda signal_no , frame : force_shutdown ( ) )
signal . signal ( signal . SIGTERM , lambda signal_no , frame : shutdown ( ) )