Commit 896900f1 authored by Julien Muchembled's avatar Julien Muchembled

fixup! client: fix cache invalidation during a load from a storage for the same oid

parent 20628341
......@@ -225,21 +225,24 @@ class ClientCache(object):
def invalidate(self, oid, tid):
"""Mark data record as being valid only up to given tid"""
item = self._oid_dict[oid][-1]
if item.next_tid is None:
item.next_tid = tid
try:
item = self._oid_dict[oid][-1]
except KeyError:
pass
else:
assert item.next_tid <= tid, (item, oid, tid)
if item.next_tid is None:
item.next_tid = tid
else:
assert item.next_tid <= tid, (item, oid, tid)
def test(self):
cache = ClientCache()
self.assertEqual(cache.load(1, 10), None)
self.assertEqual(cache.load(1, None), None)
self.assertRaises(KeyError, cache.invalidate, 1, 10)
cache.invalidate(1, 10)
data = '5', 5, 10
# 2 identical stores happens if 2 threads got a cache miss at the same time
# (which currently never happens in NEO, due to a lock)
cache.store(1, *data)
cache.store(1, *data)
self.assertEqual(cache.load(1, 10), data)
......
......@@ -110,10 +110,7 @@ class PrimaryNotificationsHandler(BaseHandler):
# was modified).
continue
# Update ex-latest value in cache
try:
cache.invalidate(oid, tid)
except KeyError:
pass
cache.invalidate(oid, tid)
if data is not None:
# Store in cache with no next_tid
cache.store(oid, data, tid, None)
......@@ -142,12 +139,10 @@ class PrimaryNotificationsHandler(BaseHandler):
invalidate = app._cache.invalidate
loading = app._loading_oid
for oid in oid_list:
try:
invalidate(oid, tid)
except KeyError:
if oid == loading:
app._loading_oid = None
app._loading_invalidated = tid
invalidate(oid, tid)
if oid == loading:
app._loading_oid = None
app._loading_invalidated = tid
db = app.getDB()
if db is not None:
db.invalidate(tid, oid_list)
......
......@@ -538,6 +538,7 @@ class Test(NEOThreadedTest):
cluster = NEOCluster()
try:
cluster.start()
cache = cluster.client._cache
# Initialize objects
t1, c1 = cluster.getTransaction()
c1.root()['x'] = x1 = PCounter()
......@@ -571,7 +572,7 @@ class Test(NEOThreadedTest):
# storage node to return original value of x, even if we
# haven't processed yet any invalidation for x.
x2 = c2.root()['x']
cluster.client._cache.clear() # bypass cache
cache.clear() # bypass cache
self.assertEqual(x2.value, 0)
finally:
master_client()
......@@ -592,7 +593,7 @@ class Test(NEOThreadedTest):
l1.release()
l2.acquire()
x2._p_deactivate()
cluster.client._cache.clear()
cache._remove(cache._oid_dict[x2._p_oid].pop())
p = Patch(cluster.client, _loadFromStorage=_loadFromStorage)
try:
t = self.newThread(x2._p_activate)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment