Skip to content

Commit 927ec9e

Browse files
committed
Provide better visibility on jobs timing out
Job timeouts are handled by setting an alarm to fire after the desired timeout, however there's currently nothing to explicitly log the failure. Introduce a handler which logs these instances but otherwise does not change the behaviour.
1 parent dd79c5f commit 927ec9e

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

django_lightweight_queue/worker.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,13 +159,25 @@ def configure_cancellation(self, timeout: Optional[int], sigkill_on_stop: bool)
159159
signal.signal(signal.SIGUSR2, self._handle_sigusr2)
160160

161161
if timeout is not None:
162+
signal.signal(signal.SIGALRM, self._handle_alarm)
162163
# alarm(3) takes whole seconds
163164
alarm_duration = int(math.ceil(timeout))
164165
signal.alarm(alarm_duration)
165166
else:
166167
# Cancel any scheduled alarms
167168
signal.alarm(0)
168169

170+
def _handle_alarm(self, signal_number: int, frame: object) -> None:
171+
# Log for observability
172+
self.log(logging.ERROR, "Alarm received: job has timed out")
173+
174+
# Disconnect ourselves then re-signal so that Python does what it
175+
# normally would. We could raise an exception here, however raising
176+
# exceptions from signal handlers is generally discouraged.
177+
signal.signal(signal.SIGALRM, signal.SIG_DFL)
178+
# TODO(python-upgrade): use signal.raise_signal on Python 3.8+
179+
os.kill(os.getpid(), signal.SIGALRM)
180+
169181
def set_process_title(self, *titles: str) -> None:
170182
set_process_title(self.name, *titles)
171183

0 commit comments

Comments
 (0)