Commit e61b017f authored by Julien Muchembled's avatar Julien Muchembled

client: fix the count of history items in the cache

Cache items are stored in double-linked chains. In order to quickly know the
number of history items, an extra attribute is used to count them. It was not
always decremented when a history item was removed.

This led to the following exception:
  <ClientCache history_size=100000 oid_count=1959 size=20970973 time=2849049 queue_length=[1, 7, 738, 355, 480, 66, 255, 44, 3, 5, 2, 1, 3, 4, 2, 2] (life_time=10000 max_history_size=100000 max_size=20971520)>
  poll raised, retrying
  Traceback (most recent call last):
    ...
    File "neo/client/handlers/master.py", line 137, in packetReceived
      cache.store(oid, data, tid, None)
    File "neo/client/cache.py", line 247, in store
      self._add(head)
    File "neo/client/cache.py", line 129, in _add
      self._remove(head)
    File "neo/client/cache.py", line 136, in _remove
      level = item.level
  AttributeError: 'NoneType' object has no attribute 'level'
parent e2536c08
...@@ -123,9 +123,8 @@ class ClientCache(object): ...@@ -123,9 +123,8 @@ class ClientCache(object):
else: else:
self._size -= len(item.data) self._size -= len(item.data)
item.data = None item.data = None
if self._history_size < self._max_history_size: self._history_size += 1
self._history_size += 1 if self._max_history_size < self._history_size:
else:
self._remove(head) self._remove(head)
item_list = self._oid_dict[head.oid] item_list = self._oid_dict[head.oid]
item_list.remove(head) item_list.remove(head)
...@@ -135,7 +134,10 @@ class ClientCache(object): ...@@ -135,7 +134,10 @@ class ClientCache(object):
def _remove(self, item): def _remove(self, item):
level = item.level level = item.level
if level is not None: if level is not None:
item.level = level - 1 if level:
item.level = level - 1
else:
self._history_size -= 1
next = item.next next = item.next
if next is item: if next is item:
self._queue_list[level] = next = None self._queue_list[level] = next = None
...@@ -208,7 +210,6 @@ class ClientCache(object): ...@@ -208,7 +210,6 @@ class ClientCache(object):
assert not item.data assert not item.data
# Possible case of late invalidation. # Possible case of late invalidation.
item.next_tid = next_tid item.next_tid = next_tid
self._history_size -= 1
else: else:
item = CacheItem() item = CacheItem()
item.oid = oid item.oid = oid
...@@ -312,6 +313,9 @@ def test(self): ...@@ -312,6 +313,9 @@ def test(self):
data = '10', 10, 15 data = '10', 10, 15
cache.store(1, *data) cache.store(1, *data)
self.assertEqual(cache.load(1, 15), data) self.assertEqual(cache.load(1, 15), data)
self.assertEqual(1, cache._history_size)
cache.clear_current()
self.assertEqual(0, cache._history_size)
if __name__ == '__main__': if __name__ == '__main__':
import unittest import unittest
......
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