Commit 89955cc3 authored by Jacob Burch's avatar Jacob Burch Committed by Aymeric Augustin
Browse files

Fixed #9595 -- Allow non-expiring cache timeouts.

Also, streamline the use of 0 and None between cache backends.
parent e0df6471
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -123,6 +123,7 @@ answer newbie questions, and generally made Django that much better:
    bthomas
    btoll@bestweb.net
    Jonathan Buchanan <jonathan.buchanan@gmail.com>
    Jacob Burch <jacobburch@gmail.com>
    Keith Bussell <kbussell@gmail.com>
    C8E
    Chris Cahoon <chris.cahoon@gmail.com>
+7 −3
Original line number Diff line number Diff line
@@ -15,6 +15,10 @@ class CacheKeyWarning(DjangoRuntimeWarning):
    pass


# Stub class to ensure not passing in a `timeout` argument results in
# the default timeout
DEFAULT_TIMEOUT = object()

# Memcached does not accept keys longer than this.
MEMCACHE_MAX_KEY_LENGTH = 250

@@ -84,7 +88,7 @@ class BaseCache(object):
        new_key = self.key_func(key, self.key_prefix, version)
        return new_key

    def add(self, key, value, timeout=None, version=None):
    def add(self, key, value, timeout=DEFAULT_TIMEOUT, version=None):
        """
        Set a value in the cache if the key does not already exist. If
        timeout is given, that timeout will be used for the key; otherwise
@@ -101,7 +105,7 @@ class BaseCache(object):
        """
        raise NotImplementedError

    def set(self, key, value, timeout=None, version=None):
    def set(self, key, value, timeout=DEFAULT_TIMEOUT, version=None):
        """
        Set a value in the cache. If timeout is given, that timeout will be
        used for the key; otherwise the default cache timeout will be used.
@@ -163,7 +167,7 @@ class BaseCache(object):
        # if a subclass overrides it.
        return self.has_key(key)

    def set_many(self, data, timeout=None, version=None):
    def set_many(self, data, timeout=DEFAULT_TIMEOUT, version=None):
        """
        Set a bunch of values in the cache at once from a dict of key/value
        pairs.  For certain backends (memcached), this is much more efficient
+9 −6
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@ except ImportError:
    import pickle

from django.conf import settings
from django.core.cache.backends.base import BaseCache
from django.core.cache.backends.base import BaseCache, DEFAULT_TIMEOUT
from django.db import connections, transaction, router, DatabaseError
from django.utils import timezone, six
from django.utils.encoding import force_bytes
@@ -65,6 +65,7 @@ class DatabaseCache(BaseDatabaseCache):
        if row is None:
            return default
        now = timezone.now()

        if row[2] < now:
            db = router.db_for_write(self.cache_model_class)
            cursor = connections[db].cursor()
@@ -74,18 +75,18 @@ class DatabaseCache(BaseDatabaseCache):
        value = connections[db].ops.process_clob(row[1])
        return pickle.loads(base64.b64decode(force_bytes(value)))

    def set(self, key, value, timeout=None, version=None):
    def set(self, key, value, timeout=DEFAULT_TIMEOUT, version=None):
        key = self.make_key(key, version=version)
        self.validate_key(key)
        self._base_set('set', key, value, timeout)

    def add(self, key, value, timeout=None, version=None):
    def add(self, key, value, timeout=DEFAULT_TIMEOUT, version=None):
        key = self.make_key(key, version=version)
        self.validate_key(key)
        return self._base_set('add', key, value, timeout)

    def _base_set(self, mode, key, value, timeout=None):
        if timeout is None:
    def _base_set(self, mode, key, value, timeout=DEFAULT_TIMEOUT):
        if timeout == DEFAULT_TIMEOUT:
            timeout = self.default_timeout
        db = router.db_for_write(self.cache_model_class)
        table = connections[db].ops.quote_name(self._table)
@@ -95,7 +96,9 @@ class DatabaseCache(BaseDatabaseCache):
        num = cursor.fetchone()[0]
        now = timezone.now()
        now = now.replace(microsecond=0)
        if settings.USE_TZ:
        if timeout is None:
            exp = datetime.max
        elif settings.USE_TZ:
            exp = datetime.utcfromtimestamp(time.time() + timeout)
        else:
            exp = datetime.fromtimestamp(time.time() + timeout)
+4 −4
Original line number Diff line number Diff line
"Dummy cache backend"

from django.core.cache.backends.base import BaseCache
from django.core.cache.backends.base import BaseCache, DEFAULT_TIMEOUT

class DummyCache(BaseCache):
    def __init__(self, host, *args, **kwargs):
        BaseCache.__init__(self, *args, **kwargs)

    def add(self, key, value, timeout=None, version=None):
    def add(self, key, value, timeout=DEFAULT_TIMEOUT, version=None):
        key = self.make_key(key, version=version)
        self.validate_key(key)
        return True
@@ -16,7 +16,7 @@ class DummyCache(BaseCache):
        self.validate_key(key)
        return default

    def set(self, key, value, timeout=None, version=None):
    def set(self, key, value, timeout=DEFAULT_TIMEOUT, version=None):
        key = self.make_key(key, version=version)
        self.validate_key(key)

@@ -32,7 +32,7 @@ class DummyCache(BaseCache):
        self.validate_key(key)
        return False

    def set_many(self, data, timeout=0, version=None):
    def set_many(self, data, timeout=DEFAULT_TIMEOUT, version=None):
        pass

    def delete_many(self, keys, version=None):
+8 −7
Original line number Diff line number Diff line
@@ -9,9 +9,10 @@ try:
except ImportError:
    import pickle

from django.core.cache.backends.base import BaseCache
from django.core.cache.backends.base import BaseCache, DEFAULT_TIMEOUT
from django.utils.encoding import force_bytes


class FileBasedCache(BaseCache):
    def __init__(self, dir, params):
        BaseCache.__init__(self, params)
@@ -19,7 +20,7 @@ class FileBasedCache(BaseCache):
        if not os.path.exists(self._dir):
            self._createdir()

    def add(self, key, value, timeout=None, version=None):
    def add(self, key, value, timeout=DEFAULT_TIMEOUT, version=None):
        if self.has_key(key, version=version):
            return False

@@ -35,7 +36,7 @@ class FileBasedCache(BaseCache):
            with open(fname, 'rb') as f:
                exp = pickle.load(f)
                now = time.time()
                if exp < now:
                if exp is not None and exp < now:
                    self._delete(fname)
                else:
                    return pickle.load(f)
@@ -43,14 +44,14 @@ class FileBasedCache(BaseCache):
            pass
        return default

    def set(self, key, value, timeout=None, version=None):
    def set(self, key, value, timeout=DEFAULT_TIMEOUT, version=None):
        key = self.make_key(key, version=version)
        self.validate_key(key)

        fname = self._key_to_file(key)
        dirname = os.path.dirname(fname)

        if timeout is None:
        if timeout == DEFAULT_TIMEOUT:
            timeout = self.default_timeout

        self._cull()
@@ -60,8 +61,8 @@ class FileBasedCache(BaseCache):
                os.makedirs(dirname)

            with open(fname, 'wb') as f:
                now = time.time()
                pickle.dump(now + timeout, f, pickle.HIGHEST_PROTOCOL)
                expiry = None if timeout is None else time.time() + timeout
                pickle.dump(expiry, f, pickle.HIGHEST_PROTOCOL)
                pickle.dump(value, f, pickle.HIGHEST_PROTOCOL)
        except (IOError, OSError):
            pass
Loading