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.