Skip to content

Commit

Permalink
Updates transaction handling to work with the latest invalidation sys…
Browse files Browse the repository at this point in the history
…tem.
  • Loading branch information
BertrandBordage committed Nov 24, 2014
1 parent c09d95e commit 22ace2e
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 29 deletions.
12 changes: 7 additions & 5 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@ What’s new in django-cachalot?
master
------

- Caches all queries implying ``Queryset.extra``
- Adds a setting to choose if random queries must be cached
- Invalidates raw queries
- Adds a simple API containing:
``invalidate_tables``, ``invalidate_models``, ``invalidate_all``
- Uses an infinite timeout
- Rewrites invalidation for a better speed & memory performance
- Fixes a stale cache issue occurring when an invalidation is done
exactly during a SQL request on the invalidated table(s)
- Uses infinite timeout
- Adds a setting to choose if random queries must be cached
- Caches all queries implying ``Queryset.extra``
- Invalidates raw queries
- Fixes a stale cache issue occurring after concurrent transactions
- Adds 2 settings to customize how cache keys are generated
- Rewrites invalidation for a better speed & memory performance
- Adds a benchmark


0.8.1
Expand Down
2 changes: 1 addition & 1 deletion cachalot/tests/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,5 @@ def test_invalidate_all_in_atomic(self):
with self.assertNumQueries(1):
Test.objects.get()

with self.assertNumQueries(0):
with self.assertNumQueries(1):
Test.objects.get()
3 changes: 2 additions & 1 deletion cachalot/tests/transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,5 +187,6 @@ def test_unsuccessful_nested_write_atomic(self):
raise ZeroDivisionError
except ZeroDivisionError:
pass
data3 = list(Test.objects.all())
with self.assertNumQueries(1):
data3 = list(Test.objects.all())
self.assertListEqual(data3, [t1])
20 changes: 4 additions & 16 deletions cachalot/transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,44 +9,32 @@ class AtomicCache(dict):
def __init__(self, parent_cache):
super(AtomicCache, self).__init__()
self.parent_cache = parent_cache
self.deleted = set()
self.to_be_invalidated = set()

def get(self, k, default=None):
if k in self.deleted:
return default
if k in self:
return self[k]
return self.parent_cache.get(k, default)

def set(self, k, v, timeout):
if k in self.deleted:
self.deleted.remove(k)
self[k] = v

def add(self, k, v, timeout):
if k not in self:
if self.get(k) is None:
self.set(k, v, timeout)

def get_many(self, keys):
data = dict([(k, self[k]) for k in keys if k in self])
missing_keys = set(keys)
missing_keys.difference_update(self.deleted)
missing_keys.difference_update(data)
data.update(self.parent_cache.get_many(missing_keys))
return data

def set_many(self, data, timeout):
self.deleted.difference_update(data)
self.update(data)

def delete_many(self, keys):
self.deleted.update(keys)
for k in keys:
if k in self:
del self[k]

def commit(self):
_invalidate_table_cache_keys(self.parent_cache,
list(self.to_be_invalidated))
self.parent_cache.set_many(self, None)
# The previous `set_many` is not enough. The parent cache needs to be
# invalidated in case another transaction occurred in the meantime.
_invalidate_table_cache_keys(self.parent_cache, self.to_be_invalidated)
6 changes: 0 additions & 6 deletions docs/todo.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,3 @@ For version 1.0
...............

- Cache raw queries

Weaknesses to be tested
.......................

- A stale cache issue should never happen when a table is invalidated
exactly during a SQL read query (fixed, but never tested in the test suite)

0 comments on commit 22ace2e

Please sign in to comment.