Skip to content

Commit

Permalink
BaseCache now has a no-op close method as per ticket django#18582
Browse files Browse the repository at this point in the history
Also removed the hasattr check when firing request_finished signal for
caches with a 'close' method. Should be safe to call `cache.close`
everywhere now
  • Loading branch information
mgrouchy committed Jul 18, 2012
1 parent 8184aff commit a2e927b
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 5 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ answer newbie questions, and generally made Django that much better:
Simon Greenhill <dev@simon.net.nz>
Owen Griffiths
Espen Grindhaug <http://grindhaug.org/>
Mike Grouchy <http://mikegrouchy.com/>
Janos Guljas
Thomas Güttler <hv@tbz-pariv.de>
Horst Gutmann <zerok@zerokspot.com>
Expand Down
8 changes: 3 additions & 5 deletions django/core/cache/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,9 @@ def get_cache(backend, **kwargs):
"Could not find backend '%s': %s" % (backend, e))
cache = backend_cls(location, params)
# Some caches -- python-memcached in particular -- need to do a cleanup at the
# end of a request cycle. If the cache provides a close() method, wire it up
# here.
if hasattr(cache, 'close'):
signals.request_finished.connect(cache.close)
# end of a request cycle. If not implemented in a particular backend
# cache.close is a no-op
signals.request_finished.connect(cache.close)
return cache

cache = get_cache(DEFAULT_CACHE_ALIAS)

9 changes: 9 additions & 0 deletions django/core/cache/backends/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,18 @@
from django.utils.encoding import smart_str
from django.utils.importlib import import_module


class InvalidCacheBackendError(ImproperlyConfigured):
pass


class CacheKeyWarning(DjangoRuntimeWarning):
pass

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


def default_key_func(key, key_prefix, version):
"""
Default function to generate keys.
Expand All @@ -25,6 +28,7 @@ def default_key_func(key, key_prefix, version):
"""
return ':'.join([key_prefix, str(version), smart_str(key)])


def get_key_func(key_func):
"""
Function to decide which key function to use.
Expand All @@ -40,6 +44,7 @@ def get_key_func(key_func):
return getattr(key_func_module, key_func_name)
return default_key_func


class BaseCache(object):
def __init__(self, params):
timeout = params.get('timeout', params.get('TIMEOUT', 300))
Expand Down Expand Up @@ -221,3 +226,7 @@ def decr_version(self, key, delta=1, version=None):
the new version.
"""
return self.incr_version(key, -delta, version)

def close(self, **kwargs):
"""Close the cache connection"""
pass
10 changes: 10 additions & 0 deletions docs/topics/cache.txt
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,16 @@ nonexistent cache key.::
However, if the backend doesn't natively provide an increment/decrement
operation, it will be implemented using a two-step retrieve/update.


You can close the connection to your cache with ``close()`` if implemented by
the cache backend.

>>> cache.close()

.. note::

For caches that don't implement ``close`` methods it is a no-op.

.. _cache_key_prefixing:

Cache key prefixing
Expand Down
4 changes: 4 additions & 0 deletions tests/regressiontests/cache/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,10 @@ def test_decr(self):
self.assertEqual(self.cache.get('answer'), 32)
self.assertRaises(ValueError, self.cache.decr, 'does_not_exist')

def test_close(self):
self.assertTrue(hasattr(self.cache, 'close'))
self.cache.close()

def test_data_types(self):
# Many different data types can be cached
stuff = {
Expand Down

0 comments on commit a2e927b

Please sign in to comment.