Skip to content

Commit

Permalink
Adds CACHALOT_TIMEOUT.
Browse files Browse the repository at this point in the history
  • Loading branch information
BertrandBordage committed Sep 6, 2016
1 parent 7624564 commit 571e6ec
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 3 deletions.
5 changes: 3 additions & 2 deletions cachalot/monkey_patch.py
Expand Up @@ -42,7 +42,8 @@ def _get_result_or_execute_query(execute_query_func, cache,

if new_table_cache_keys:
now = time()
cache.set_many({k: now for k in new_table_cache_keys}, None)
cache.set_many({k: now for k in new_table_cache_keys},
cachalot_settings.CACHALOT_TIMEOUT)
elif cache_key in data:
timestamp, result = data.pop(cache_key)
table_times = data.values()
Expand All @@ -53,7 +54,7 @@ def _get_result_or_execute_query(execute_query_func, cache,
if isinstance(result, Iterable) and result.__class__ not in TUPLE_OR_LIST:
result = list(result)

cache.set(cache_key, (time(), result), None)
cache.set(cache_key, (time(), result), cachalot_settings.CACHALOT_TIMEOUT)

return result

Expand Down
1 change: 1 addition & 0 deletions cachalot/settings.py
Expand Up @@ -4,6 +4,7 @@
class Settings(object):
CACHALOT_ENABLED = True
CACHALOT_CACHE = 'default'
CACHALOT_TIMEOUT = None
CACHALOT_CACHE_RANDOM = False
CACHALOT_INVALIDATE_RAW = True
CACHALOT_ONLY_CACHABLE_TABLES = frozenset()
Expand Down
29 changes: 29 additions & 0 deletions cachalot/tests/settings.py
@@ -1,6 +1,7 @@
# coding: utf-8

from __future__ import unicode_literals
from time import sleep
from unittest import skipIf

from django.conf import settings
Expand All @@ -10,6 +11,7 @@
from django.test import TransactionTestCase
from django.test.utils import override_settings

from ..api import invalidate
from .models import Test, TestParent, TestChild


Expand Down Expand Up @@ -82,6 +84,33 @@ def test_cache(self):
with self.assertNumQueries(0):
list(Test.objects.all())

def test_cache_timeout(self):
with self.assertNumQueries(1):
list(Test.objects.all())
sleep(1)
with self.assertNumQueries(0):
list(Test.objects.all())

invalidate(Test)

with self.settings(CACHALOT_TIMEOUT=0):
with self.assertNumQueries(1):
list(Test.objects.all())
sleep(0.05)
with self.assertNumQueries(1):
list(Test.objects.all())

# We have to test with a full second and not a shorter time because
# memcached only takes the integer part of the timeout into account.
with self.settings(CACHALOT_TIMEOUT=1):
with self.assertNumQueries(1):
list(Test.objects.all())
with self.assertNumQueries(0):
list(Test.objects.all())
sleep(1)
with self.assertNumQueries(1):
list(Test.objects.all())

def test_cache_random(self):
with self.assertNumQueries(1):
list(Test.objects.order_by('?'))
Expand Down
19 changes: 18 additions & 1 deletion docs/quickstart.rst
Expand Up @@ -61,6 +61,23 @@ Settings
.. |CACHES| replace:: ``CACHES``
.. _CACHES: https://docs.djangoproject.com/en/1.7/ref/settings/#std:setting-CACHES

``CACHALOT_TIMEOUT``
~~~~~~~~~~~~~~~~~~~~

:Default: ``None``
:Description:
Number of seconds during which the cache should consider data as valid.
``None`` means an infinite timeout.

.. warning::
Cache timeouts don’t work in a strict way on most cache backends.
A cache might not keep a cache key during the requested timeout:
it can keep it in memory during a shorter time than the specified timeout.
It can even keep it longer, even if data is not returned when you request it.
So **don’t rely on timeouts to limit the size of your database**,
you might face some unexpected behaviour.
Always set the maximum cache size instead.

``CACHALOT_CACHE_RANDOM``
~~~~~~~~~~~~~~~~~~~~~~~~~

Expand All @@ -86,7 +103,7 @@ Settings
Sequence of SQL table names that will be the only ones django-cachalot
will cache. Only queries with a subset of these tables will be cached.
The sequence being empty (as it is by default) doesn’t mean that no table
can be cached: it disables this setting, so any table can be cache.
can be cached: it disables this setting, so any table can be cached.
:ref:`CACHALOT_UNCACHABLE_TABLES` has more weight than this:
if you add a table to both settings, it will never be cached.
Use a frozenset over other sequence types for a tiny performance boost.
Expand Down

0 comments on commit 571e6ec

Please sign in to comment.