Commit 1fc7c4ae authored by Russell Keith-Magee's avatar Russell Keith-Magee
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
parent ed51dd5d
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -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
+2 −12
Original line number Diff line number Diff line
@@ -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)
+0 −13
Original line number Diff line number Diff line
@@ -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()
+0 −13
Original line number Diff line number Diff line
@@ -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):
+26 −19
Original line number Diff line number Diff line
@@ -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,11 +421,14 @@ 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)
@@ -440,7 +447,7 @@ if settings.CACHE_BACKEND.startswith('memcached://'):
        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):
    """