Runner shunts message being processed when receiving SIGTERM
When a runner process receives SIGTERM (or SIGINT, SIGUSR1) while processing a queue message, the signal handler raises RunnerInterrupt which interrupts _dispose() mid-execution. The interrupted message is then shunted to the shunt queue, even though it could have been processed to completion.
The signal handler in Runner.signal_handler() raises RunnerInterrupt:
elif signum in (signal.SIGTERM, signal.SIGINT, signal.SIGUSR1):
self.stop()
self.status = signum
raise RunnerInterrupt
This exception propagates up through _process_one_file() → _one_iteration(), where it is caught as a generic Exception and the message is shunted:
except Exception as error:
...
shunt = config.switchboards['shunt']
new_filebase = shunt.enqueue(msg, msgdata)
Additionally, the RetryRunner uses time.sleep() which, due to PEP 475, automatically retries at the C layer after signal delivery. The RunnerInterrupt exception was introduced as a workaround for this, but it has the side effect of interrupting message processing.