Merge lp:~cjwatson/rabbitfixture/signal-esrch into lp:rabbitfixture

Proposed by Colin Watson
Status: Merged
Merged at revision: 55
Proposed branch: lp:~cjwatson/rabbitfixture/signal-esrch
Merge into: lp:rabbitfixture
Diff against target: 41 lines (+16/-4)
2 files modified
NEWS.rst (+7/-0)
rabbitfixture/server.py (+9/-4)
To merge this branch: bzr merge lp:~cjwatson/rabbitfixture/signal-esrch
Reviewer Review Type Date Requested Status
Jürgen Gmach Approve
Review via email: mp+427306@code.launchpad.net

Commit message

Ignore ESRCH errors in RabbitServerRunner._signal.

Description of the change

This can happen if the server process exits by itself just before we try to signal it.

To post a comment you must log in.
Revision history for this message
Jürgen Gmach (jugmac00) wrote :

How did you come up with this solution?

review: Approve
Revision history for this message
Colin Watson (cjwatson) wrote :

I saw http://lpbuildbot.canonical.com/builders/lp-db-devel-xenial/builds/2297/steps/shell/logs/summary, which wasn't quite the exact failure mode I remembered noticing before, and asked myself "how could that happen?". Since the code immediately preceding that was a check for whether the process is still running, the obvious answer was that it must be a race: the process exited by itself between the check for whether it was still running and the attempt to send a signal to it.

The private `_signal` method is only used to send various signals to the process that are intended to terminate it, either cooperatively (`SIGTERM`) or abruptly (`SIGKILL`). Therefore, it is not a problem if the process has already gone away, and the right answer is to simply ignore errors that mean that.

Finally, since `rabbitfixture` hasn't yet dropped Python 2 support and I didn't want to block a fix for this bug on that, I looked up https://docs.python.org/3/library/exceptions.html to confirm that `ProcessLookupError` corresponds to `ESRCH` and used the old approach of catching `OSError` and filtering by `errno` rather than catching `ProcessLookupError` directly, since that's only two more lines of code.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'NEWS.rst'
2--- NEWS.rst 2021-02-02 10:56:39 +0000
3+++ NEWS.rst 2022-07-22 19:43:08 +0000
4@@ -2,6 +2,13 @@
5 NEWS for rabbitfixture
6 ======================
7
8+0.5.1
9+=====
10+
11+- Ignore ``ESRCH`` errors in ``RabbitServerRunner._signal``, since this can
12+ happen if the server process exits by itself just before we try to signal
13+ it.
14+
15 0.5.0 (2021-02-02)
16 ==================
17
18
19=== modified file 'rabbitfixture/server.py'
20--- rabbitfixture/server.py 2021-02-01 13:15:24 +0000
21+++ rabbitfixture/server.py 2022-07-22 19:43:08 +0000
22@@ -465,10 +465,15 @@
23 def _signal(self, code):
24 """Send a signal to the server process and all its children."""
25 # We need to send the signal to the process group, since on Ubuntu
26- # 14.04 an later /usr/sbin/rabbitmq-server is a shell script wrapper
27- # that spawns the actual Erlang runtime sub-process which what does
28- # actually do the work and listen for connections.
29- os.killpg(os.getpgid(self.process.pid), code)
30+ # 14.04 and later /usr/sbin/rabbitmq-server is a shell script
31+ # wrapper that spawns the actual Erlang runtime sub-process which is
32+ # what actually does the work and listens for connections.
33+ try:
34+ os.killpg(os.getpgid(self.process.pid), code)
35+ except OSError as e:
36+ if e.errno == errno.ESRCH:
37+ pass
38+ raise
39
40
41 class RabbitServer(Fixture):

Subscribers

People subscribed via source and target branches

to all changes: