Eventlet green threads not released back to pool
Presently, the wsgi server allows persist connections. Hence even after the response is sent to the client, it doesn't close the client socket connection. Because of this problem, the green thread is not released back to the pool. In order to close the client socket connection explicitly after the response is sent and read successfully by the client, you simply have to set keepalive to False when you create a wsgi server. DocImpact: Added http_keepalive option (default=True). SecurityImpact Closes-Bug: #1361360 Change-Id: I93aaca24935a4f3096210233097dd6b8c5440176
This commit is contained in:
parent
78b5b0a957
commit
16a821e00d
@ -1441,3 +1441,14 @@ return a ValueError exception with "No such digest method" error.
|
||||
* ``digest_algorithm=<algorithm>``
|
||||
|
||||
Optional. Default: ``sha1``
|
||||
|
||||
Configuring http_keepalive option
|
||||
----------------------------------
|
||||
|
||||
* ``http_keepalive=<True|False>``
|
||||
|
||||
If False, server will return the header "Connection: close", If True, server
|
||||
will return "Connection: Keep-Alive" in its responses. In order to close the
|
||||
client socket connection explicitly after the response is sent and read
|
||||
successfully by the client, you simply have to set this option to False when
|
||||
you create a wsgi server.
|
||||
|
@ -105,6 +105,13 @@ backlog = 4096
|
||||
# represent the proxy's URL.
|
||||
#public_endpoint=<None>
|
||||
|
||||
# http_keepalive option. If False, server will return the header
|
||||
# "Connection: close", If True, server will return "Connection: Keep-Alive"
|
||||
# in its responses. In order to close the client socket connection
|
||||
# explicitly after the response is sent and read successfully by the client,
|
||||
# you simply have to set this option to False when you create a wsgi server.
|
||||
#http_keepalive = True
|
||||
|
||||
# ================= Syslog Options ============================
|
||||
|
||||
# Send logs to syslog (/dev/log) instead of to file specified
|
||||
|
@ -54,6 +54,13 @@ limit_param_default = 25
|
||||
# Default: False
|
||||
#sqlalchemy_debug = True
|
||||
|
||||
# http_keepalive option. If False, server will return the header
|
||||
# "Connection: close", If True, server will return "Connection: Keep-Alive"
|
||||
# in its responses. In order to close the client socket connection
|
||||
# explicitly after the response is sent and read successfully by the client,
|
||||
# you simply have to set this option to False when you create a wsgi server.
|
||||
#http_keepalive = True
|
||||
|
||||
# ================= Syslog Options ============================
|
||||
|
||||
# Send logs to syslog (/dev/log) instead of to file specified
|
||||
|
@ -88,6 +88,9 @@ eventlet_opts = [
|
||||
'max_header_line may need to be increased when using '
|
||||
'large tokens (typically those generated by the '
|
||||
'Keystone v3 API with big service catalogs')),
|
||||
cfg.BoolOpt('http_keepalive', default=True,
|
||||
help=_('If False, closes the client socket connection '
|
||||
'explicitly.')),
|
||||
]
|
||||
|
||||
profiler_opts = [
|
||||
@ -344,7 +347,8 @@ class Server(object):
|
||||
self.application,
|
||||
log=self._wsgi_logger,
|
||||
custom_pool=self.pool,
|
||||
debug=False)
|
||||
debug=False,
|
||||
keepalive=CONF.http_keepalive)
|
||||
except socket.error as err:
|
||||
if err[0] != errno.EINVAL:
|
||||
raise
|
||||
@ -355,7 +359,8 @@ class Server(object):
|
||||
LOG.info(_LI("Starting single process server"))
|
||||
eventlet.wsgi.server(sock, application, custom_pool=self.pool,
|
||||
log=self._wsgi_logger,
|
||||
debug=False)
|
||||
debug=False,
|
||||
keepalive=CONF.http_keepalive)
|
||||
|
||||
|
||||
class Middleware(object):
|
||||
|
@ -466,6 +466,28 @@ class ServerTest(test_utils.BaseTestCase):
|
||||
actual = wsgi.Server(threads=1).create_pool()
|
||||
self.assertIsInstance(actual, eventlet.greenpool.GreenPool)
|
||||
|
||||
@mock.patch.object(wsgi, 'get_socket')
|
||||
def test_http_keepalive(self, mock_get_socket):
|
||||
fake_socket = 'fake_socket'
|
||||
mock_get_socket.return_value = 'fake_socket'
|
||||
self.config(http_keepalive=False)
|
||||
self.config(workers=0)
|
||||
|
||||
server = wsgi.Server(threads=1)
|
||||
# mocking eventlet.wsgi server method to check it is called with
|
||||
# configured 'http_keepalive' value.
|
||||
with mock.patch.object(eventlet.wsgi,
|
||||
'server') as mock_server:
|
||||
fake_application = "fake-application"
|
||||
server.start(fake_application, 0)
|
||||
server.wait()
|
||||
mock_server.assert_called_once_with(fake_socket,
|
||||
fake_application,
|
||||
log=server._wsgi_logger,
|
||||
debug=False,
|
||||
custom_pool=server.pool,
|
||||
keepalive=False)
|
||||
|
||||
|
||||
class TestHelpers(test_utils.BaseTestCase):
|
||||
|
||||
|
@ -146,6 +146,7 @@ class OptsTestCase(utils.BaseTestCase):
|
||||
'config_file',
|
||||
'public_endpoint',
|
||||
'digest_algorithm',
|
||||
'http_keepalive',
|
||||
]
|
||||
|
||||
self._check_opt_groups(opt_list, expected_opt_groups)
|
||||
@ -207,6 +208,7 @@ class OptsTestCase(utils.BaseTestCase):
|
||||
'flavor',
|
||||
'config_file',
|
||||
'digest_algorithm',
|
||||
'http_keepalive',
|
||||
]
|
||||
|
||||
self._check_opt_groups(opt_list, expected_opt_groups)
|
||||
|
Loading…
x
Reference in New Issue
Block a user