forked from ansible/awx
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Give specific messages if job was killed due to SIGTERM or SIGKILL (a…
…nsible#12435) * Reap jobs on dispatcher startup to increase clarity, replace existing reaping logic * Exit jobs if receiving SIGTERM signal * Fix unwanted reaping on shutdown, let subprocess close out * Add some sanity tests for signal module * Add a log for an unhandled dispatcher error * Refine wording of error messages Co-authored-by: Elijah DeLee <kdelee@redhat.com>
- Loading branch information
Showing
8 changed files
with
165 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import signal | ||
import functools | ||
import logging | ||
|
||
|
||
logger = logging.getLogger('awx.main.tasks.signals') | ||
|
||
|
||
__all__ = ['with_signal_handling', 'signal_callback'] | ||
|
||
|
||
class SignalState: | ||
def reset(self): | ||
self.sigterm_flag = False | ||
self.is_active = False | ||
self.original_sigterm = None | ||
self.original_sigint = None | ||
|
||
def __init__(self): | ||
self.reset() | ||
|
||
def set_flag(self, *args): | ||
"""Method to pass into the python signal.signal method to receive signals""" | ||
self.sigterm_flag = True | ||
|
||
def connect_signals(self): | ||
self.original_sigterm = signal.getsignal(signal.SIGTERM) | ||
self.original_sigint = signal.getsignal(signal.SIGINT) | ||
signal.signal(signal.SIGTERM, self.set_flag) | ||
signal.signal(signal.SIGINT, self.set_flag) | ||
self.is_active = True | ||
|
||
def restore_signals(self): | ||
signal.signal(signal.SIGTERM, self.original_sigterm) | ||
signal.signal(signal.SIGINT, self.original_sigint) | ||
self.reset() | ||
|
||
|
||
signal_state = SignalState() | ||
|
||
|
||
def signal_callback(): | ||
return signal_state.sigterm_flag | ||
|
||
|
||
def with_signal_handling(f): | ||
""" | ||
Change signal handling to make signal_callback return True in event of SIGTERM or SIGINT. | ||
""" | ||
|
||
@functools.wraps(f) | ||
def _wrapped(*args, **kwargs): | ||
try: | ||
this_is_outermost_caller = False | ||
if not signal_state.is_active: | ||
signal_state.connect_signals() | ||
this_is_outermost_caller = True | ||
return f(*args, **kwargs) | ||
finally: | ||
if this_is_outermost_caller: | ||
signal_state.restore_signals() | ||
|
||
return _wrapped |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import signal | ||
|
||
from awx.main.tasks.signals import signal_state, signal_callback, with_signal_handling | ||
|
||
|
||
def test_outer_inner_signal_handling(): | ||
""" | ||
Even if the flag is set in the outer context, its value should persist in the inner context | ||
""" | ||
|
||
@with_signal_handling | ||
def f2(): | ||
assert signal_callback() | ||
|
||
@with_signal_handling | ||
def f1(): | ||
assert signal_callback() is False | ||
signal_state.set_flag() | ||
assert signal_callback() | ||
f2() | ||
|
||
original_sigterm = signal.getsignal(signal.SIGTERM) | ||
assert signal_callback() is False | ||
f1() | ||
assert signal_callback() is False | ||
assert signal.getsignal(signal.SIGTERM) is original_sigterm | ||
|
||
|
||
def test_inner_outer_signal_handling(): | ||
""" | ||
Even if the flag is set in the inner context, its value should persist in the outer context | ||
""" | ||
|
||
@with_signal_handling | ||
def f2(): | ||
assert signal_callback() is False | ||
signal_state.set_flag() | ||
assert signal_callback() | ||
|
||
@with_signal_handling | ||
def f1(): | ||
assert signal_callback() is False | ||
f2() | ||
assert signal_callback() | ||
|
||
original_sigterm = signal.getsignal(signal.SIGTERM) | ||
assert signal_callback() is False | ||
f1() | ||
assert signal_callback() is False | ||
assert signal.getsignal(signal.SIGTERM) is original_sigterm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters