diff options
| author | Barry Warsaw | 2017-01-28 13:17:25 -0500 |
|---|---|---|
| committer | Barry Warsaw | 2017-01-28 13:19:58 -0500 |
| commit | 7c97e8fbdb90a1a0de1526d7a6f108e95415d6a0 (patch) | |
| tree | d49c10cccf7bfafa08fa7145a5860fa43e5615fb /src/mailman/core | |
| parent | dfb807e04037786a62e7635d0b37e0695a77d5d6 (diff) | |
| download | mailman-7c97e8fbdb90a1a0de1526d7a6f108e95415d6a0.tar.gz mailman-7c97e8fbdb90a1a0de1526d7a6f108e95415d6a0.tar.zst mailman-7c97e8fbdb90a1a0de1526d7a6f108e95415d6a0.zip | |
Handle PEP 475 fallout.
Closes #255
As of Python 3.5, PEP 475 gets in our way. Runners with long time.sleep()'s
in their _snooze() method (e.g. the retry runner) will have their system call
implemented time.sleep() automatically retried at the C layer. The only
reliable way to prevent this is to raise an exception in the signal handler.
The standard run() method automatically suppresses this exception, meaning,
it's caught and ignored, but effectively breaks the run() loop, which is just
what we want.
The lmtp and rest runners implement their own run loops, so they also have to
handle this exception, by ignoring it.
Diffstat (limited to 'src/mailman/core')
| -rw-r--r-- | src/mailman/core/runner.py | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/src/mailman/core/runner.py b/src/mailman/core/runner.py index 757d8837e..9f8094153 100644 --- a/src/mailman/core/runner.py +++ b/src/mailman/core/runner.py @@ -31,7 +31,8 @@ from mailman.core.logging import reopen from mailman.core.switchboard import Switchboard from mailman.interfaces.languages import ILanguageManager from mailman.interfaces.listmanager import IListManager -from mailman.interfaces.runner import IRunner, RunnerCrashEvent +from mailman.interfaces.runner import ( + IRunner, RunnerCrashEvent, RunnerInterrupt) from mailman.utilities.string import expand from public import public from zope.component import getUtility @@ -98,6 +99,16 @@ class Runner: elif signum == signal.SIGHUP: reopen() rlog.info('%s runner caught SIGHUP. Reopening logs.', self.name) + # As of Python 3.5, PEP 475 gets in our way. Runners with long + # time.sleep()'s in their _snooze() method (e.g. the retry runner) will + # have their system call implemented time.sleep() automatically retried + # at the C layer. The only reliable way to prevent this is to raise an + # exception in the signal handler. The standard run() method + # automatically suppresses this exception, meaning, it's caught and + # ignored, but effectively breaks the run() loop, which is just what we + # want. Runners which implement their own run() method must be + # prepared to catch RunnerInterrupts, usually also ignoring them. + raise RunnerInterrupt def set_signals(self): """See `IRunner`.""" @@ -113,7 +124,7 @@ class Runner: def run(self): """See `IRunner`.""" # Start the main loop for this runner. - with suppress(KeyboardInterrupt): + with suppress(KeyboardInterrupt, RunnerInterrupt): while True: # Once through the loop that processes all the files in the # queue directory. |
