mirror of
https://github.com/frappe/gunicorn.git
synced 2026-01-14 11:09:11 +08:00
[arbiter] close sockets on shutdown
Close all the listeners when the arbiter shuts down. By doing so, workers can close the socket at the beginning of a graceful shut down thereby informing the operating system that the socket can be cleaned up. With this change, graceful exits with such workers will refuse new connections while draining, allowing load balancers to respond more quickly and avoiding leaving connections dangling in the listen backlog, unaccepted. Ref #922
This commit is contained in:
parent
e05941cec2
commit
39cecbc8e9
@ -334,6 +334,8 @@ class Arbiter(object):
|
||||
:attr graceful: boolean, If True (the default) workers will be
|
||||
killed gracefully (ie. trying to wait for the current connection)
|
||||
"""
|
||||
for l in self.LISTENERS:
|
||||
l.close()
|
||||
self.LISTENERS = []
|
||||
sig = signal.SIGTERM
|
||||
if not graceful:
|
||||
|
||||
@ -5,15 +5,18 @@
|
||||
|
||||
import os
|
||||
|
||||
try:
|
||||
import unittest.mock as mock
|
||||
except ImportError:
|
||||
import mock
|
||||
|
||||
import gunicorn.app.base
|
||||
import gunicorn.arbiter
|
||||
|
||||
|
||||
class PreloadedAppWithEnvSettings(gunicorn.app.base.BaseApplication):
|
||||
class DummyApplication(gunicorn.app.base.BaseApplication):
|
||||
"""
|
||||
Simple application that makes use of the 'preload' feature to
|
||||
start the application before spawning worker processes and sets
|
||||
environmental variable configuration settings.
|
||||
Dummy application that has an default configuration.
|
||||
"""
|
||||
|
||||
def init(self, parser, opts, args):
|
||||
@ -22,6 +25,27 @@ class PreloadedAppWithEnvSettings(gunicorn.app.base.BaseApplication):
|
||||
def load(self):
|
||||
"""No-op"""
|
||||
|
||||
def load_config(self):
|
||||
"""No-op"""
|
||||
|
||||
|
||||
def test_arbiter_shutdown_closes_listeners():
|
||||
arbiter = gunicorn.arbiter.Arbiter(DummyApplication())
|
||||
listener1 = mock.Mock()
|
||||
listener2 = mock.Mock()
|
||||
arbiter.LISTENERS = [listener1, listener2]
|
||||
arbiter.stop()
|
||||
listener1.close.assert_called_with()
|
||||
listener2.close.assert_called_with()
|
||||
|
||||
|
||||
class PreloadedAppWithEnvSettings(DummyApplication):
|
||||
"""
|
||||
Simple application that makes use of the 'preload' feature to
|
||||
start the application before spawning worker processes and sets
|
||||
environmental variable configuration settings.
|
||||
"""
|
||||
|
||||
def load_config(self):
|
||||
"""Set the 'preload_app' and 'raw_env' settings in order to verify their
|
||||
interaction below.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user