Skip to content

Commit

Permalink
Fixed inconsistent cache read of concurrent threads
Browse files Browse the repository at this point in the history
  • Loading branch information
andbag committed Apr 15, 2018
1 parent dbe1a0d commit 88d0d90
Show file tree
Hide file tree
Showing 13 changed files with 171 additions and 54 deletions.
10 changes: 5 additions & 5 deletions src/Products/PluginIndexes/BooleanIndex/tests.py
Expand Up @@ -257,19 +257,19 @@ def test_reindexation_when_index_reversed(self):
def test_getCounter(self):
index = self._makeOne()

self.assertEqual(index.getCounter(), 0)
self.assertEqual(index.getCounter(), (0, False))

obj = Dummy(1, True)
index.index_object(obj.id, obj)
self.assertEqual(index.getCounter(), 1)
self.assertEqual(index.getCounter(), (1, False))

index.unindex_object(obj.id)
self.assertEqual(index.getCounter(), 2)
self.assertEqual(index.getCounter(), (2, False))

# unknown id
index.unindex_object(1234)
self.assertEqual(index.getCounter(), 2)
self.assertEqual(index.getCounter(), (2, False))

# clear is a change
index.clear()
self.assertEqual(index.getCounter(), 3)
self.assertEqual(index.getCounter(), (3, False))
10 changes: 5 additions & 5 deletions src/Products/PluginIndexes/DateIndex/tests.py
Expand Up @@ -337,21 +337,21 @@ def test_getCounter(self):
from DateTime import DateTime

index = self._makeOne()
self.assertEqual(index.getCounter(), 0)
self.assertEqual(index.getCounter(), (0, False))

index.index_object(1, Dummy('b', DateTime(0)))
self.assertEqual(index.getCounter(), 1)
self.assertEqual(index.getCounter(), (1, False))

index.unindex_object(1)
self.assertEqual(index.getCounter(), 2)
self.assertEqual(index.getCounter(), (2, False))

# unknown id
index.unindex_object(1234)
self.assertEqual(index.getCounter(), 2)
self.assertEqual(index.getCounter(), (2, False))

# clear is a change
index.clear()
self.assertEqual(index.getCounter(), 3)
self.assertEqual(index.getCounter(), (3, False))

def test_precision(self):
from DateTime import DateTime
Expand Down
10 changes: 5 additions & 5 deletions src/Products/PluginIndexes/DateRangeIndex/tests.py
Expand Up @@ -284,22 +284,22 @@ def test_resultset(self):

def test_getCounter(self):
index = self._makeOne('work', 'start', 'stop')
self.assertEqual(index.getCounter(), 0)
self.assertEqual(index.getCounter(), (0, False))

k, obj = dummies[0]
index.index_object(k, obj)
self.assertEqual(index.getCounter(), 1)
self.assertEqual(index.getCounter(), (1, False))

index.unindex_object(k)
self.assertEqual(index.getCounter(), 2)
self.assertEqual(index.getCounter(), (2, False))

# unknown id
index.unindex_object(1234)
self.assertEqual(index.getCounter(), 2)
self.assertEqual(index.getCounter(), (2, False))

# clear is a change
index.clear()
self.assertEqual(index.getCounter(), 3)
self.assertEqual(index.getCounter(), (3, False))

def test_precision(self):
precision = 5
Expand Down
10 changes: 5 additions & 5 deletions src/Products/PluginIndexes/KeywordIndex/tests.py
Expand Up @@ -275,19 +275,19 @@ def test_value_removes(self):
def test_getCounter(self):
index = self._makeOne('foo')

self.assertEqual(index.getCounter(), 0)
self.assertEqual(index.getCounter(), (0, False))

obj = Dummy(['hello'])
index.index_object(10, obj)
self.assertEqual(index.getCounter(), 1)
self.assertEqual(index.getCounter(), (1, False))

index.unindex_object(10)
self.assertEqual(index.getCounter(), 2)
self.assertEqual(index.getCounter(), (2, False))

# unknown id
index.unindex_object(1234)
self.assertEqual(index.getCounter(), 2)
self.assertEqual(index.getCounter(), (2, False))

# clear is a change
index.clear()
self.assertEqual(index.getCounter(), 3)
self.assertEqual(index.getCounter(), (3, False))
6 changes: 5 additions & 1 deletion src/Products/PluginIndexes/PathIndex/PathIndex.py
Expand Up @@ -198,7 +198,11 @@ def _increment_counter(self):

def getCounter(self):
"""Return a counter which is increased on index changes"""
return self._counter is not None and self._counter() or 0
counter = self._counter is not None and self._counter() or 0
changed = (self._counter is not None and
self._counter._p_changed or False)

return (counter, changed)

def numObjects(self):
""" See IPluggableIndex.
Expand Down
10 changes: 5 additions & 5 deletions src/Products/PluginIndexes/PathIndex/tests.py
Expand Up @@ -537,19 +537,19 @@ def test__search_w_level_0(self):
def test_getCounter(self):
index = self._makeOne()

self.assertEqual(index.getCounter(), 0)
self.assertEqual(index.getCounter(), (0, False))

doc = Dummy('/aa/bb')
index.index_object(1, doc)
self.assertEqual(index.getCounter(), 1)
self.assertEqual(index.getCounter(), (1, False))

index.unindex_object(1)
self.assertEqual(index.getCounter(), 2)
self.assertEqual(index.getCounter(), (2, False))

# unknown id
index.unindex_object(1)
self.assertEqual(index.getCounter(), 2)
self.assertEqual(index.getCounter(), (2, False))

# clear changes the index
index.clear()
self.assertEqual(index.getCounter(), 3)
self.assertEqual(index.getCounter(), (3, False))
6 changes: 5 additions & 1 deletion src/Products/PluginIndexes/TopicIndex/TopicIndex.py
Expand Up @@ -101,7 +101,11 @@ def _increment_counter(self):

def getCounter(self):
"""Return a counter which is increased on index changes"""
return self._counter is not None and self._counter() or 0
counter = self._counter is not None and self._counter() or 0
changed = (self._counter is not None and
self._counter._p_changed or False)

return (counter, changed)

def numObjects(self):
"""Return the number of indexed objects."""
Expand Down
10 changes: 5 additions & 5 deletions src/Products/PluginIndexes/TopicIndex/tests.py
Expand Up @@ -97,18 +97,18 @@ def test_getCounter(self):
index = self.TI
index._counter.set(0)

self.assertEqual(index.getCounter(), 0)
self.assertEqual(index.getCounter(), (0, False))

index.index_object(1, Obj(1, 'doc1'))
self.assertEqual(index.getCounter(), 1)
self.assertEqual(index.getCounter(), (1, False))

index.unindex_object(1)
self.assertEqual(index.getCounter(), 2)
self.assertEqual(index.getCounter(), (2, False))

# unknown id
index.unindex_object(1)
self.assertEqual(index.getCounter(), 2)
self.assertEqual(index.getCounter(), (2, False))

# clear changes the index
index.clear()
self.assertEqual(index.getCounter(), 3)
self.assertEqual(index.getCounter(), (3, False))
10 changes: 5 additions & 5 deletions src/Products/PluginIndexes/UUIDIndex/tests.py
Expand Up @@ -179,19 +179,19 @@ def test_non_unique(self):
def test_getCounter(self):
index = self._makeOne('foo')

self.assertEqual(index.getCounter(), 0)
self.assertEqual(index.getCounter(), (0, False))

obj = Dummy('a')
index.index_object(10, obj)
self.assertEqual(index.getCounter(), 1)
self.assertEqual(index.getCounter(), (1, False))

index.unindex_object(10)
self.assertEqual(index.getCounter(), 2)
self.assertEqual(index.getCounter(), (2, False))

# unknown id
index.unindex_object(1234)
self.assertEqual(index.getCounter(), 2)
self.assertEqual(index.getCounter(), (2, False))

# clear is a change
index.clear()
self.assertEqual(index.getCounter(), 3)
self.assertEqual(index.getCounter(), (3, False))
13 changes: 8 additions & 5 deletions src/Products/PluginIndexes/tests/test_unindex.py
Expand Up @@ -25,6 +25,7 @@ def _getTargetClass(self):
return UnIndex

def _makeOne(self, *args, **kw):

index = self._getTargetClass()(*args, **kw)

class DummyZCatalog(SimpleItem):
Expand Down Expand Up @@ -142,25 +143,27 @@ def testQuery(record, expect=1):
testQuery(record)

def test_getCounter(self):

index = self._makeOne('counter')

self.assertEqual(index.getCounter(), 0)
self.assertEqual(index.getCounter(), (0, False))

class Dummy(object):
id = 1
counter = 'counter'

obj = Dummy()
index.index_object(obj.id, obj)
self.assertEqual(index.getCounter(), 1)
self.assertEqual(index.getCounter(), (1, False))

index.unindex_object(obj.id)
self.assertEqual(index.getCounter(), 2)
self.assertEqual(index.getCounter(), (2, False))

# unknown id
index.unindex_object(1234)
self.assertEqual(index.getCounter(), 2)
self.assertEqual(index.getCounter(), (2, False))

# clear changes the index
index.clear()
self.assertEqual(index.getCounter(), 3)
self.assertEqual(index.getCounter(), (3, False))

6 changes: 5 additions & 1 deletion src/Products/PluginIndexes/unindex.py
Expand Up @@ -297,7 +297,11 @@ def _increment_counter(self):

def getCounter(self):
"""Return a counter which is increased on index changes"""
return self._counter is not None and self._counter() or 0
counter = self._counter is not None and self._counter() or 0
changed = (self._counter is not None and
self._counter._p_changed or False)

return (counter, changed)

def numObjects(self):
"""Return the number of indexed objects."""
Expand Down
6 changes: 5 additions & 1 deletion src/Products/ZCatalog/cache.py
Expand Up @@ -63,7 +63,11 @@ def skip(name, value):
if name in catalog.indexes:
index = catalog.getIndex(name)
if IIndexCounter.providedBy(index):
counter = index.getCounter()
counter, changed = index.getCounter()

# cannot cache if index was updated
if changed:
return None
else:
# cache key invalidation cannot be supported if
# any index of query cannot be tested for changes
Expand Down

0 comments on commit 88d0d90

Please sign in to comment.