diff options
| author | Olivier Dony <odo@openerp.com> | 2017-09-25 11:22:09 +0200 |
|---|---|---|
| committer | Olivier Dony <odo@openerp.com> | 2017-09-25 11:22:09 +0200 |
| commit | e98e8e9b1bdf8c3a3bcf74b7648b0829c21d356a (patch) | |
| tree | 414a43594a980a438e698fdcaf2c84cce8a1e6ab /addons/web/static/src/js/fields/basic_fields.js | |
| parent | d03b4f867539298019576e74c638a0148fe87bc2 (diff) | |
[FIX] P3: fix server shutdown on Ctrl+C
This is an attempt at fixing the long timeout occurring on P3 when
trying to stop the server with Ctrl-C, both in multithreaded and
multi-process mode.
The root cause is the implementation of PEP-0475[1] as of Python 3.5,
which make system calls silently resume after an interrupt.
With this PEP, interrupting a syscall now requires the signal handler to
raise an exception, which get propagated in places where they did not
use to occur (e.g. time.sleep() used to return early when interrupted)
The solution handles 2 separate cases:
1. Multithreaded
In multithreaded mode, stopping the server requires interrupting
the main thread, while ensuring that all other threads are daemon ones.
The previous commit fixed the latter.
Interrupting the main thread is easy, because it simply sleeps until
it gets interrupted. And it already catches KeyboardInterrupt for
win32 quirks. All we need to do is thus to raise a KeyboardInterrupt
in the signal handler, as proposed in PEP 475 (Use Case 2)
2. Multi-process
In multi-process mode, stopping the server requires interrupting the
main thread of each process. The signal is already propagated to all
processes, so it should be as simple as for multithreaded mode.
Unfortunately, the main threads are far from idle in this case,
and raising a KeyboardInterrupt from the signal handler causes a
series of ugly tracebacks before stopping the server.
Effective, but frightening for the admin.
Instead of doing that, we can watch the wakeup file descriptor
(also suggested in PEP 475, Use Case 2) during the sleep() part of the
main loop of each worker. An interrupt signal won't therefore stop
the server immediately, but will wait until each worker is done with
their current request.. even better.
For select() syscalls, this is done with an extra pipe fd that is passed in
the "read fds", and used as wakeup fd.
And for sleep() syscalls, that don't support a wakeup fd, we can
replace them with an equivalent select() call on the wakeup fd, and
a timeout.
The combination of the above seems to restore a relatively fast
interrupt shutdown on both Python 2.7 and Python 3.5, in both
multithreaded and multi-process mode, with no surprising traceback.
[1] https://www.python.org/dev/peps/pep-0475/
Diffstat (limited to 'addons/web/static/src/js/fields/basic_fields.js')
0 files changed, 0 insertions, 0 deletions
