Belle II Software  release-08-01-10
CleanBasf2Execution Class Reference

Public Member Functions

def __init__ (self, timeout=10)
 
def start (self, command)
 
def wait (self)
 
def signal_handler (self, signal_number, signal_frame)
 
def kill (self)
 
def wait_for_process (self, process_list=None, timeout=None, minimum_delay=1)
 
def install_signal_handler (self)
 

Static Public Member Functions

def has_process_ended (process)
 

Public Attributes

 timeout
 Maximum time the process is allowed to stay alive after SIGTERM has been sent.
 

Private Attributes

 _handled_processes
 The processes handled by this class.
 
 _handled_commands
 The commands related to the processes.
 

Detailed Description

Helper class to call a given (basf2) command via subprocess
and make sure the process is killed properly once a SIGINT or SIGTERM signal is
send to the main process.
To do this, the basf2 command is started in a new session group, so all child processes
of the basf2 command will also be killed.

When the main process receives a termination request via an SIGINT or SIGTERM,
a SIGINT is sent to the started basf2 process.
If the process is still alive after a given timeout (10 s by default),
it is killed via SIGKILL and all its started child forks with it.
After a normal or abnormal termination, the run() function returns the exit code
and cleanup can happen afterwards.

ATTENTION: In some rare cases, e.g. when the terminate request happens during a syscall,
the process can not be stopped (see uninterruptable sleep process state, e.g. in
https://stackoverflow.com/questions/223644/what-is-an-uninterruptable-process).
In those cases, even a KILL signal does not help!

The class can be used in a typical main method, e.g.

    from hlt.clean_execution import CleanBasf2Execution

    if __name__ == "__main__":
        execution = CleanBasf2Execution()
        try:
            execution.start(["basf2", "run.py"])
            execution.wait()
        finally:
            # Make sure to always do the cleanup, also in case of errors
            print("Do cleanup")

Definition at line 16 of file clean_execution.py.

Constructor & Destructor Documentation

◆ __init__()

def __init__ (   self,
  timeout = 10 
)
Create a new execution with the given parameters (list of arguments)

Definition at line 51 of file clean_execution.py.

51  def __init__(self, timeout=10):
52  """
53  Create a new execution with the given parameters (list of arguments)
54  """
55 
56  self._handled_processes = []
57 
58  self._handled_commands = []
59 
60  self.timeout = timeout
61 

Member Function Documentation

◆ has_process_ended()

def has_process_ended (   process)
static
Check if the handled process has ended already.
This functions does not wait.

I would rather use self._handled_process.wait() or poll()
which does exactly the same.
However: the main process is also waiting for the return code
so the threading.lock in the .wait() function will never aquire a lock :-(

Definition at line 179 of file clean_execution.py.

◆ install_signal_handler()

def install_signal_handler (   self)
Set the signal handlers for SIGINT and SIGTERM to out own one.

Definition at line 168 of file clean_execution.py.

◆ kill()

def kill (   self)
Clean or hard shutdown of all processes.
It tries to kill the process gracefully but if it does not react after a certain time,
it kills it with a SIGKILL.

Definition at line 96 of file clean_execution.py.

◆ signal_handler()

def signal_handler (   self,
  signal_number,
  signal_frame 
)
The signal handler called on SIGINT and SIGTERM.

Definition at line 90 of file clean_execution.py.

◆ start()

def start (   self,
  command 
)
Add the execution and terminate gracefully/hard if requested via signal.

Definition at line 62 of file clean_execution.py.

◆ wait()

def wait (   self)
Wait until all handled calculations have finished.

Definition at line 76 of file clean_execution.py.

◆ wait_for_process()

def wait_for_process (   self,
  process_list = None,
  timeout = None,
  minimum_delay = 1 
)
Wait maximum "timeout" for the process to stop.
If it did not end in this period, returns False.

Definition at line 145 of file clean_execution.py.


The documentation for this class was generated from the following file: