Stops automatically invalidating other caches than `CACHALOT_CACHE`.

This had a negative impact on performance, and it was not working reliably.
It is clearer to invalidate only `CACHALOT_CACHE`, and to detail what
to do in the docs when we change `CACHALOT_CACHE`.
This commit is contained in:
Bertrand Bordage 2016-09-29 19:11:21 +02:00
parent eb64d1ce2b
commit f6cfeb6226
3 changed files with 24 additions and 24 deletions

View File

@ -9,7 +9,8 @@ from django.db.backends.utils import CursorWrapper
from django.db.models.query import EmptyResultSet
from django.db.models.signals import post_migrate
from django.db.models.sql.compiler import (
SQLCompiler, SQLInsertCompiler, SQLUpdateCompiler, SQLDeleteCompiler)
SQLCompiler, SQLInsertCompiler, SQLUpdateCompiler, SQLDeleteCompiler,
)
from django.db.transaction import Atomic, get_connection
from django.utils.six import binary_type
@ -18,8 +19,8 @@ from .cache import cachalot_caches
from .settings import cachalot_settings
from .utils import (
_get_query_cache_key, _get_table_cache_keys, _get_tables_from_sql,
_invalidate_table, UncachableQuery, TUPLE_OR_LIST, is_cachable,
filter_cachable)
UncachableQuery, TUPLE_OR_LIST, is_cachable, filter_cachable,
)
WRITE_COMPILERS = (SQLInsertCompiler, SQLUpdateCompiler, SQLDeleteCompiler)
@ -90,8 +91,8 @@ def _patch_write_compiler(original):
db_alias = write_compiler.using
table = write_compiler.query.get_meta().db_table
if is_cachable(table):
_invalidate_table(cachalot_caches.get_cache(db_alias=db_alias),
db_alias, table)
invalidate(table, db_alias=db_alias,
cache_alias=cachalot_settings.CACHALOT_CACHE)
return original(write_compiler, *args, **kwargs)
return inner
@ -117,7 +118,8 @@ def _patch_cursor():
tables = filter_cachable(
set(_get_tables_from_sql(cursor.db, sql)))
if tables:
invalidate(*tables, db_alias=cursor.db.alias)
invalidate(*tables, db_alias=cursor.db.alias,
cache_alias=cachalot_settings.CACHALOT_CACHE)
return out
return inner
@ -150,7 +152,8 @@ def _patch_atomic():
def _invalidate_on_migration(sender, **kwargs):
invalidate(*sender.get_models(), db_alias=kwargs['using'])
invalidate(*sender.get_models(), db_alias=kwargs['using'],
cache_alias=cachalot_settings.CACHALOT_CACHE)
def patch():

View File

@ -69,21 +69,32 @@ class SettingsTestCase(TransactionTestCase):
@skipIf(len(settings.CACHES) == 1,
'We cant change the cache used since theres only one configured')
def test_cache(self):
other_cache_alias = next(alias for alias in settings.CACHES
if alias != DEFAULT_CACHE_ALIAS)
invalidate(Test, cache_alias=other_cache_alias)
with self.settings(CACHALOT_CACHE=DEFAULT_CACHE_ALIAS):
with self.assertNumQueries(1):
list(Test.objects.all())
with self.assertNumQueries(0):
list(Test.objects.all())
other_cache_alias = next(alias for alias in settings.CACHES
if alias != DEFAULT_CACHE_ALIAS)
with self.settings(CACHALOT_CACHE=other_cache_alias):
with self.assertNumQueries(1):
list(Test.objects.all())
with self.assertNumQueries(0):
list(Test.objects.all())
Test.objects.create(name='test')
# Only `CACHALOT_CACHE` is invalidated, so changing the database should
# not invalidate all caches.
with self.settings(CACHALOT_CACHE=other_cache_alias):
with self.assertNumQueries(0):
list(Test.objects.all())
with self.assertNumQueries(0):
list(Test.objects.all())
def test_cache_timeout(self):
with self.assertNumQueries(1):
list(Test.objects.all())

View File

@ -15,7 +15,6 @@ from django.utils.module_loading import import_string
from django.utils.six import text_type, binary_type
from .settings import cachalot_settings
from .signals import post_invalidation
from .transaction import AtomicCache
@ -191,16 +190,3 @@ def _invalidate_tables(cache, db_alias, tables):
if isinstance(cache, AtomicCache):
cache.to_be_invalidated.update(tables)
def _invalidate_table(cache, db_alias, table):
if not is_cachable(table):
return
cache.set(_get_table_cache_key(db_alias, table), time(),
cachalot_settings.CACHALOT_TIMEOUT)
if isinstance(cache, AtomicCache):
cache.to_be_invalidated.add(table)
else:
post_invalidation.send(table, db_alias=db_alias)