Redis: Support socket keepalive
redis-py supports socket keepalive feature. This updates the config build process so that users can use this feature by the existing socket keepalive options. Change-Id: I396e7af9d1e1e04e56a11d26ffea506f2b675a18
This commit is contained in:
parent
e8de6c9ea5
commit
fd8d8889b8
@ -35,6 +35,7 @@ The library has special public value for nonexistent or expired keys called
|
||||
NO_VALUE = core.NO_VALUE
|
||||
"""
|
||||
import re
|
||||
import socket
|
||||
import ssl
|
||||
import urllib.parse
|
||||
|
||||
@ -311,21 +312,35 @@ def _build_cache_config(conf):
|
||||
# and running or if it has broken.
|
||||
# This could be used by users who want to handle fine grained failures.
|
||||
if conf.cache.enable_socket_keepalive:
|
||||
if conf.cache.backend != 'dogpile.cache.pymemcache':
|
||||
msg = _(
|
||||
"Socket keepalive is only supported by the "
|
||||
"'dogpile.cache.pymemcache' backend."
|
||||
if conf.cache.backend == 'dogpile.cache.pymemcache':
|
||||
import pymemcache
|
||||
socket_keepalive = pymemcache.KeepaliveOpts(
|
||||
idle=conf.cache.socket_keepalive_idle,
|
||||
intvl=conf.cache.socket_keepalive_interval,
|
||||
cnt=conf.cache.socket_keepalive_count)
|
||||
# As with the TLS context above, the config dict below will be
|
||||
# consumed by dogpile.cache that will be used as a proxy between
|
||||
# oslo.cache and pymemcache.
|
||||
conf_dict['%s.arguments.socket_keepalive' % prefix] = \
|
||||
socket_keepalive
|
||||
elif conf.cache.backend in ('dogpile.cache.redis',
|
||||
'dogpile.cache.redis_sentinel'):
|
||||
socket_keepalive_options = {
|
||||
socket.TCP_KEEPIDLE: conf.cache.socket_keepalive_idle,
|
||||
socket.TCP_KEEPINTVL: conf.cache.socket_keepalive_interval,
|
||||
socket.TCP_KEEPCNT: conf.cache.socket_keepalive_count
|
||||
}
|
||||
conf_dict.setdefault(
|
||||
'%s.arguments.connection_kwargs' % prefix, {}
|
||||
).update({
|
||||
'socket_keepalive': True,
|
||||
'socket_keepalive_options': socket_keepalive_options
|
||||
})
|
||||
else:
|
||||
raise exception.ConfigurationError(
|
||||
"Socket keepalive is not supported by the %s backend"
|
||||
% conf.cache.backend
|
||||
)
|
||||
raise exception.ConfigurationError(msg)
|
||||
import pymemcache
|
||||
socket_keepalive = pymemcache.KeepaliveOpts(
|
||||
idle=conf.cache.socket_keepalive_idle,
|
||||
intvl=conf.cache.socket_keepalive_interval,
|
||||
cnt=conf.cache.socket_keepalive_count)
|
||||
# As with the TLS context above, the config dict below will be
|
||||
# consumed by dogpile.cache that will be used as a proxy between
|
||||
# oslo.cache and pymemcache.
|
||||
conf_dict['%s.arguments.socket_keepalive' % prefix] = socket_keepalive
|
||||
|
||||
# NOTE(hberaud): The pymemcache library comes with retry mechanisms that
|
||||
# can be used to wrap all kind of pymemcache clients. The retry wrapper
|
||||
|
@ -14,6 +14,7 @@
|
||||
# under the License.
|
||||
|
||||
import copy
|
||||
import socket
|
||||
import ssl
|
||||
import time
|
||||
from unittest import mock
|
||||
@ -769,6 +770,53 @@ class CacheRegionTest(test_cache.BaseTestCase):
|
||||
self.assertEqual(
|
||||
1.0, config_dict['test_prefix.arguments.socket_timeout'])
|
||||
|
||||
def test_cache_dictionary_config_builder_redis_with_keepalive(self):
|
||||
"""Validate the backend is reset to default if caching is disabled."""
|
||||
self.config_fixture.config(group='cache',
|
||||
config_prefix='test_prefix',
|
||||
backend='dogpile.cache.redis',
|
||||
redis_server='[::1]:6379',
|
||||
enable_socket_keepalive=True)
|
||||
|
||||
config_dict = cache._build_cache_config(self.config_fixture.conf)
|
||||
self.assertEqual(
|
||||
'redis://[::1]:6379',
|
||||
config_dict['test_prefix.arguments.url'])
|
||||
self.assertEqual(
|
||||
1.0, config_dict['test_prefix.arguments.socket_timeout'])
|
||||
self.assertEqual({
|
||||
'socket_keepalive': True,
|
||||
'socket_keepalive_options': {
|
||||
socket.TCP_KEEPIDLE: 1,
|
||||
socket.TCP_KEEPINTVL: 1,
|
||||
socket.TCP_KEEPCNT: 1,
|
||||
}}, config_dict['test_prefix.arguments.connection_kwargs'])
|
||||
|
||||
def test_cache_dictionary_config_builder_redis_with_keepalive_params(self):
|
||||
"""Validate the backend is reset to default if caching is disabled."""
|
||||
self.config_fixture.config(group='cache',
|
||||
config_prefix='test_prefix',
|
||||
backend='dogpile.cache.redis',
|
||||
redis_server='[::1]:6379',
|
||||
enable_socket_keepalive=True,
|
||||
socket_keepalive_idle=2,
|
||||
socket_keepalive_interval=3,
|
||||
socket_keepalive_count=4)
|
||||
|
||||
config_dict = cache._build_cache_config(self.config_fixture.conf)
|
||||
self.assertEqual(
|
||||
'redis://[::1]:6379',
|
||||
config_dict['test_prefix.arguments.url'])
|
||||
self.assertEqual(
|
||||
1.0, config_dict['test_prefix.arguments.socket_timeout'])
|
||||
self.assertEqual({
|
||||
'socket_keepalive': True,
|
||||
'socket_keepalive_options': {
|
||||
socket.TCP_KEEPIDLE: 2,
|
||||
socket.TCP_KEEPINTVL: 3,
|
||||
socket.TCP_KEEPCNT: 4,
|
||||
}}, config_dict['test_prefix.arguments.connection_kwargs'])
|
||||
|
||||
def test_cache_dictionary_config_builder_redis_with_auth(self):
|
||||
"""Validate the backend is reset to default if caching is disabled."""
|
||||
self.config_fixture.config(group='cache',
|
||||
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
The ``dogpile.cache.redis`` backend and ``dogpile.cache.redis_sentinel``
|
||||
backend now supports enabling socket keepalive configurations by
|
||||
setting the ``[cache] enable_socket_keepalive`` option to ``True``. Use
|
||||
the ``socket_keepalive_*`` options to tune keepalive behavior.
|
Loading…
Reference in New Issue
Block a user