Skip to content

Commit 9c56fbc

Browse files
committed
Handle SIGTERM signal as an interruption flow
Signed-off-by: Sylvain Hellegouarch <sh@defuze.org>
1 parent 13b33c6 commit 9c56fbc

File tree

2 files changed

+25
-4
lines changed

2 files changed

+25
-4
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44

55
[Unreleased]: https://github.com/chaostoolkit/chaostoolkit-lib/compare/1.14.0...HEAD
66

7+
### Added
8+
9+
- SIGTERM signal is now listened for. This triggers the interruption mechanism
10+
of the experiment.
11+
712
## [1.14.0][] - 2020-09-09
813

914
[1.14.0]: https://github.com/chaostoolkit/chaostoolkit-lib/compare/1.13.1...1.14.0

chaoslib/exit.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,10 @@ def my_probe():
5555
@contextmanager
5656
def 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

8997
def 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

Comments
 (0)