Skip to content
Snippets Groups Projects
Commit d56e8227 authored by Holger's avatar Holger
Browse files

Add option use_del to ObjectCache, for making the cache thread safe

parent 3c89719e
No related branches found
No related tags found
No related merge requests found
......@@ -14,10 +14,11 @@ import json
@python_2_unicode_compatible
class ObjectCache(dict):
def __init__(self, initial_data={}, default_expiration=10, auto_clean=True):
def __init__(self, initial_data={}, default_expiration=10, auto_clean=True, use_del=True):
super(ObjectCache, self).__init__(initial_data)
self.default_expiration = default_expiration
self.auto_clean = auto_clean
self.use_del = use_del
def __setitem__(self, key, value):
if key in self:
......@@ -34,11 +35,15 @@ class ObjectCache(dict):
def __getitem__(self, key):
if key in self:
value = dict.__getitem__(self, key)
return value["data"]
if value is not None:
return value["data"]
def get(self, key, default):
if key in self:
return self[key]
if self[key] is not None:
return self[key]
else:
return default
else:
return default
......@@ -48,12 +53,19 @@ class ObjectCache(dict):
keys.append(key)
for key in keys:
value = dict.__getitem__(self, key)
if value is None:
continue
if datetime.utcnow() >= value["expires"]:
del self[key]
if self.use_del:
del self[key]
else:
self[key] = None
def __contains__(self, key):
if dict.__contains__(self, key):
value = dict.__getitem__(self, key)
if value is None:
return False
if datetime.utcnow() < value["expires"]:
return True
else:
......@@ -63,8 +75,15 @@ class ObjectCache(dict):
def __str__(self):
if self.auto_clean:
self.clear_expired_items()
n = 0
if self.use_del:
n = len(list(self.keys()))
else:
for key in self:
if self[key] is not None:
n += 1
return "ObjectCache(n={}, default_expiration={})".format(
len(list(self.keys())), self.default_expiration)
n, self.default_expiration)
class BlockchainObject(dict):
......@@ -169,12 +188,18 @@ class BlockchainObject(dict):
def set_cache_auto_clean(self, auto_clean):
BlockchainObject._cache.auto_clean = auto_clean
def set_cache_use_del(self, use_del):
BlockchainObject._cache.use_del = use_del
def get_cache_expiration(self):
return BlockchainObject._cache.default_expiration
def get_cache_auto_clean(self):
return BlockchainObject._cache.auto_clean
def get_cache_use_del(self):
return BlockchainObject._cache.use_del
def iscached(self, id):
return id in BlockchainObject._cache
......
......@@ -48,6 +48,26 @@ class Testcases(unittest.TestCase):
time.sleep(2)
self.assertNotIn("foo", cache)
self.assertEqual(str(cache), "ObjectCache(n=0, default_expiration=1)")
self.assertEqual(len(list(cache)), 0)
# Get
self.assertEqual(cache.get("foo", "New"), "New")
def test_use_del(self):
cache = ObjectCache(default_expiration=1, auto_clean=True, use_del=False)
self.assertEqual(str(cache), "ObjectCache(n=0, default_expiration=1)")
# Data
cache["foo"] = "bar"
self.assertEqual(str(cache), "ObjectCache(n=1, default_expiration=1)")
self.assertIn("foo", cache)
self.assertEqual(cache["foo"], "bar")
self.assertEqual(cache.get("foo", "New"), "bar")
# Expiration
time.sleep(2)
self.assertNotIn("foo", cache)
self.assertEqual(str(cache), "ObjectCache(n=0, default_expiration=1)")
self.assertEqual(len(list(cache)), 1)
# Get
self.assertEqual(cache.get("foo", "New"), "New")
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment