@@ -55,9 +55,10 @@ def my_probe():
5555@contextmanager
5656def exit_signals ():
5757 """
58- Register the handlers for SIGUSR1 and SIGUSR2 signals. Puts back the
59- original handlers when the call ends.
58+ Register the handlers for SIGTERM, SIGUSR1 and SIGUSR2 signals.
59+ Puts back the original handlers when the call ends.
6060
61+ SIGTERM will trigger an InterruptExecution exception
6162 SIGUSR1 is used to terminate the experiment now while keeping the
6263 rollbacks if they were declared.
6364 SIGUSR2 is used to terminate the experiment without ever running the
@@ -66,24 +67,31 @@ def exit_signals():
6667 Generally speaking using signals this way is a bit of an overkill but
6768 the Python VM has no other mechanism to interrupt blocking calls.
6869
69- WARNING: Only available on Unix/Linux systems.
70+ WARNING: SIGUSR1 and SIGUSR2 are only available on Unix/Linux systems.
7071 """
72+ sigterm_handler = signal .signal (signal .SIGTERM , _terminate_now )
73+
7174 if hasattr (signal , "SIGUSR1" ) and hasattr (signal , "SIGUSR2" ):
7275 # keep a reference to the original handlers
7376 sigusr1_handler = signal .signal (signal .SIGUSR1 , _leave_now )
7477 sigusr2_handler = signal .signal (signal .SIGUSR2 , _leave_now )
7578 try :
7679 yield
7780 finally :
81+ signal .signal (signal .SIGTERM , sigterm_handler )
7882 signal .signal (signal .SIGUSR1 , sigusr1_handler )
7983 signal .signal (signal .SIGUSR2 , sigusr2_handler )
8084 else :
85+
8186 # On a system that doesn't support SIGUSR signals
8287 # not much we can do...
8388 logger .debug (
8489 "System '{}' does not expose SIGUSR signals" .format (
8590 platform .platform ()))
86- yield
91+ try :
92+ yield
93+ finally :
94+ signal .signal (signal .SIGTERM , sigterm_handler )
8795
8896
8997def exit_gracefully ():
@@ -142,3 +150,11 @@ def _leave_now(signum: int, frame: FrameType = None) -> None:
142150
143151 elif signum == signal .SIGUSR2 :
144152 raise SystemExit (30 )
153+
154+
155+ def _terminate_now (signum : int , frame : FrameType = None ) -> None :
156+ """
157+ Signal handler for the SIGTERM event. Raises an `InterruptExecution`.
158+ """
159+ if signum == signal .SIGTERM :
160+ logger .warning ("Caught SIGTERM signal, interrupting experiment now" )
0 commit comments