Refs #29887, Refs #24212 -- Added servers configuration hook for memcached backends.

The servers property can be overridden to allow memcached backends to
alter the server configuration prior to it being passed to instantiate
the client. This allows avoidance of documentation for per-backend
differences, e.g. stripping the 'unix:' prefix for pylibmc.
This commit is contained in:
Nick Pope 2020-08-15 21:34:32 +01:00 committed by Mariusz Felisiak
parent 0bf627f0b2
commit a629139425
3 changed files with 24 additions and 10 deletions

View File

@ -26,12 +26,16 @@ class BaseMemcachedCache(BaseCache):
self._class = library.Client self._class = library.Client
self._options = params.get('OPTIONS') or {} self._options = params.get('OPTIONS') or {}
@property
def client_servers(self):
return self._servers
@cached_property @cached_property
def _cache(self): def _cache(self):
""" """
Implement transparent thread-safe access to a memcached client. Implement transparent thread-safe access to a memcached client.
""" """
return self._class(self._servers, **self._options) return self._class(self.client_servers, **self._options)
def get_backend_timeout(self, timeout=DEFAULT_TIMEOUT): def get_backend_timeout(self, timeout=DEFAULT_TIMEOUT):
""" """
@ -192,6 +196,13 @@ class PyLibMCCache(BaseMemcachedCache):
import pylibmc import pylibmc
super().__init__(server, params, library=pylibmc, value_not_found_exception=pylibmc.NotFound) super().__init__(server, params, library=pylibmc, value_not_found_exception=pylibmc.NotFound)
@property
def client_servers(self):
output = []
for server in self._servers:
output.append(server[5:] if server.startswith('unix:') else server)
return output
def touch(self, key, timeout=DEFAULT_TIMEOUT, version=None): def touch(self, key, timeout=DEFAULT_TIMEOUT, version=None):
key = self.make_key(key, version=version) key = self.make_key(key, version=version)
self.validate_key(key) self.validate_key(key)

View File

@ -114,15 +114,6 @@ In this example, Memcached is available through a local Unix socket file
} }
} }
When using the ``pylibmc`` binding, do not include the ``unix:/`` prefix::
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
'LOCATION': '/tmp/memcached.sock',
}
}
One excellent feature of Memcached is its ability to share a cache over One excellent feature of Memcached is its ability to share a cache over
multiple servers. This means you can run Memcached daemons on multiple multiple servers. This means you can run Memcached daemons on multiple
machines, and the program will treat the group of machines as a *single* machines, and the program will treat the group of machines as a *single*

12
tests/cache/tests.py vendored
View File

@ -1441,6 +1441,18 @@ class PyLibMCCacheTests(BaseMemcachedTests, TestCase):
self.assertTrue(cache._cache.binary) self.assertTrue(cache._cache.binary)
self.assertEqual(cache._cache.behaviors['tcp_nodelay'], int(True)) self.assertEqual(cache._cache.behaviors['tcp_nodelay'], int(True))
def test_pylibmc_client_servers(self):
backend = self.base_params['BACKEND']
tests = [
('unix:/run/memcached/socket', '/run/memcached/socket'),
('/run/memcached/socket', '/run/memcached/socket'),
('127.0.0.1:11211', '127.0.0.1:11211'),
]
for location, expected in tests:
settings = {'default': {'BACKEND': backend, 'LOCATION': location}}
with self.subTest(location), self.settings(CACHES=settings):
self.assertEqual(cache.client_servers, [expected])
@override_settings(CACHES=caches_setting_for_tests( @override_settings(CACHES=caches_setting_for_tests(
BACKEND='django.core.cache.backends.filebased.FileBasedCache', BACKEND='django.core.cache.backends.filebased.FileBasedCache',