Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

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
  • Loading branch information...
commit 1fc7c4aee44af3d5c55d3532aa8fb5b2d9102a62 1 parent ed51dd5
@freakboy3742 freakboy3742 authored
View
12 django/core/cache/backends/base.py
@@ -22,6 +22,18 @@ def __init__(self, params):
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
View
14 django/core/cache/backends/db.py
@@ -25,7 +25,7 @@ def __init__(self, table):
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 CacheEntry(object):
_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)
View
13 django/core/cache/backends/filebased.py
@@ -14,19 +14,6 @@
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()
View
13 django/core/cache/backends/locmem.py
@@ -14,19 +14,6 @@ def __init__(self, _, params):
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):
View
45 tests/regressiontests/cache/tests.py
@@ -410,6 +410,10 @@ def tearDown(self):
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 @@ def setUp(self):
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)
-
- 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')
+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.
+
+ 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):
"""

0 comments on commit 1fc7c4a

Please sign in to comment.
Something went wrong with that request. Please try again.