Prevent removal unix socket for reuse_port (#1887)

If you have two (or more) instances of gunicorn that use `reuse-port`
and bind to single unix socket all work until one of gunicorn will
stopped. Because the first stopped removes unix socket file and other
instances can't longer process requests.
This commit is contained in:
Konstantin vz'One Enchant 2018-10-02 14:25:35 +03:00 committed by Benoit Chesneau
parent eae3ef05f3
commit 927fb2ba02
2 changed files with 15 additions and 2 deletions

View File

@ -375,8 +375,11 @@ class Arbiter(object):
:attr graceful: boolean, If True (the default) workers will be
killed gracefully (ie. trying to wait for the current connection)
"""
unlink = self.reexec_pid == self.master_pid == 0 and not self.systemd
unlink = (
self.reexec_pid == self.master_pid == 0
and not self.systemd
and not self.cfg.reuse_port
)
sock.close_sockets(self.LISTENERS, unlink)
self.LISTENERS = []

View File

@ -12,6 +12,7 @@ except ImportError:
import gunicorn.app.base
import gunicorn.arbiter
from gunicorn.config import ReusePort
class DummyApplication(gunicorn.app.base.BaseApplication):
@ -64,6 +65,15 @@ def test_arbiter_stop_does_not_unlink_systemd_listeners(close_sockets):
close_sockets.assert_called_with([], False)
@mock.patch('gunicorn.sock.close_sockets')
def test_arbiter_stop_does_not_unlink_when_using_reuse_port(close_sockets):
arbiter = gunicorn.arbiter.Arbiter(DummyApplication())
arbiter.cfg.settings['reuse_port'] = ReusePort()
arbiter.cfg.settings['reuse_port'].set(True)
arbiter.stop()
close_sockets.assert_called_with([], False)
@mock.patch('os.getpid')
@mock.patch('os.fork')
@mock.patch('os.execvpe')