Fixed #14596 -- Light refactoring of the cache backends.
* Removes some code duplication, * Provides a convenient base class for db-like cache backends * Adds tests for an edge case of culling, * Marks the memcached tests as "skipped", rather than omitting them. Thanks to Jonas H for the patch. git-svn-id: http://code.djangoproject.com/svn/django/trunk@14434 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
ed51dd5d64
commit
1fc7c4aee4
|
@ -22,6 +22,18 @@ class BaseCache(object):
|
|||
timeout = 300
|
||||
self.default_timeout = timeout
|
||||
|
||||
max_entries = params.get('max_entries', 300)
|
||||
try:
|
||||
self._max_entries = int(max_entries)
|
||||
except (ValueError, TypeError):
|
||||
self._max_entries = 300
|
||||
|
||||
cull_frequency = params.get('cull_frequency', 3)
|
||||
try:
|
||||
self._cull_frequency = int(cull_frequency)
|
||||
except (ValueError, TypeError):
|
||||
self._cull_frequency = 3
|
||||
|
||||
def add(self, key, value, timeout=None):
|
||||
"""
|
||||
Set a value in the cache if the key does not already exist. If
|
||||
|
|
|
@ -25,7 +25,7 @@ class Options(object):
|
|||
self.managed = True
|
||||
self.proxy = False
|
||||
|
||||
class CacheClass(BaseCache):
|
||||
class BaseDatabaseCacheClass(BaseCache):
|
||||
def __init__(self, table, params):
|
||||
BaseCache.__init__(self, params)
|
||||
self._table = table
|
||||
|
@ -34,17 +34,7 @@ class CacheClass(BaseCache):
|
|||
_meta = Options(table)
|
||||
self.cache_model_class = CacheEntry
|
||||
|
||||
max_entries = params.get('max_entries', 300)
|
||||
try:
|
||||
self._max_entries = int(max_entries)
|
||||
except (ValueError, TypeError):
|
||||
self._max_entries = 300
|
||||
cull_frequency = params.get('cull_frequency', 3)
|
||||
try:
|
||||
self._cull_frequency = int(cull_frequency)
|
||||
except (ValueError, TypeError):
|
||||
self._cull_frequency = 3
|
||||
|
||||
class CacheClass(BaseDatabaseCacheClass):
|
||||
def get(self, key, default=None):
|
||||
self.validate_key(key)
|
||||
db = router.db_for_read(self.cache_model_class)
|
||||
|
|
|
@ -14,19 +14,6 @@ from django.utils.hashcompat import md5_constructor
|
|||
class CacheClass(BaseCache):
|
||||
def __init__(self, dir, params):
|
||||
BaseCache.__init__(self, params)
|
||||
|
||||
max_entries = params.get('max_entries', 300)
|
||||
try:
|
||||
self._max_entries = int(max_entries)
|
||||
except (ValueError, TypeError):
|
||||
self._max_entries = 300
|
||||
|
||||
cull_frequency = params.get('cull_frequency', 3)
|
||||
try:
|
||||
self._cull_frequency = int(cull_frequency)
|
||||
except (ValueError, TypeError):
|
||||
self._cull_frequency = 3
|
||||
|
||||
self._dir = dir
|
||||
if not os.path.exists(self._dir):
|
||||
self._createdir()
|
||||
|
|
|
@ -14,19 +14,6 @@ class CacheClass(BaseCache):
|
|||
BaseCache.__init__(self, params)
|
||||
self._cache = {}
|
||||
self._expire_info = {}
|
||||
|
||||
max_entries = params.get('max_entries', 300)
|
||||
try:
|
||||
self._max_entries = int(max_entries)
|
||||
except (ValueError, TypeError):
|
||||
self._max_entries = 300
|
||||
|
||||
cull_frequency = params.get('cull_frequency', 3)
|
||||
try:
|
||||
self._cull_frequency = int(cull_frequency)
|
||||
except (ValueError, TypeError):
|
||||
self._cull_frequency = 3
|
||||
|
||||
self._lock = RWLock()
|
||||
|
||||
def add(self, key, value, timeout=None):
|
||||
|
|
|
@ -410,6 +410,10 @@ class DBCacheTests(unittest.TestCase, BaseCacheTests):
|
|||
def test_cull(self):
|
||||
self.perform_cull_test(50, 29)
|
||||
|
||||
def test_zero_cull(self):
|
||||
self.cache = get_cache('db://%s?max_entries=30&cull_frequency=0' % self._table_name)
|
||||
self.perform_cull_test(50, 18)
|
||||
|
||||
class LocMemCacheTests(unittest.TestCase, BaseCacheTests):
|
||||
def setUp(self):
|
||||
self.cache = get_cache('locmem://?max_entries=30')
|
||||
|
@ -417,30 +421,33 @@ class LocMemCacheTests(unittest.TestCase, BaseCacheTests):
|
|||
def test_cull(self):
|
||||
self.perform_cull_test(50, 29)
|
||||
|
||||
def test_zero_cull(self):
|
||||
self.cache = get_cache('locmem://?max_entries=30&cull_frequency=0')
|
||||
self.perform_cull_test(50, 19)
|
||||
|
||||
# memcached backend isn't guaranteed to be available.
|
||||
# To check the memcached backend, the test settings file will
|
||||
# need to contain a CACHE_BACKEND setting that points at
|
||||
# your memcache server.
|
||||
if settings.CACHE_BACKEND.startswith('memcached://'):
|
||||
class MemcachedCacheTests(unittest.TestCase, BaseCacheTests):
|
||||
def setUp(self):
|
||||
self.cache = get_cache(settings.CACHE_BACKEND)
|
||||
class MemcachedCacheTests(unittest.TestCase, BaseCacheTests):
|
||||
def setUp(self):
|
||||
self.cache = get_cache(settings.CACHE_BACKEND)
|
||||
|
||||
def test_invalid_keys(self):
|
||||
"""
|
||||
On memcached, we don't introduce a duplicate key validation
|
||||
step (for speed reasons), we just let the memcached API
|
||||
library raise its own exception on bad keys. Refs #6447.
|
||||
def test_invalid_keys(self):
|
||||
"""
|
||||
On memcached, we don't introduce a duplicate key validation
|
||||
step (for speed reasons), we just let the memcached API
|
||||
library raise its own exception on bad keys. Refs #6447.
|
||||
|
||||
In order to be memcached-API-library agnostic, we only assert
|
||||
that a generic exception of some kind is raised.
|
||||
|
||||
"""
|
||||
# memcached does not allow whitespace or control characters in keys
|
||||
self.assertRaises(Exception, self.cache.set, 'key with spaces', 'value')
|
||||
# memcached limits key length to 250
|
||||
self.assertRaises(Exception, self.cache.set, 'a' * 251, 'value')
|
||||
In order to be memcached-API-library agnostic, we only assert
|
||||
that a generic exception of some kind is raised.
|
||||
|
||||
"""
|
||||
# memcached does not allow whitespace or control characters in keys
|
||||
self.assertRaises(Exception, self.cache.set, 'key with spaces', 'value')
|
||||
# memcached limits key length to 250
|
||||
self.assertRaises(Exception, self.cache.set, 'a' * 251, 'value')
|
||||
MemcachedCacheTests = unittest.skipUnless(settings.CACHE_BACKEND.startswith('memcached://'), "memcached not available")(MemcachedCacheTests)
|
||||
|
||||
class FileBasedCacheTests(unittest.TestCase, BaseCacheTests):
|
||||
"""
|
||||
|
|
Loading…
Reference in New Issue