aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Kemmer <tkemmer@computer.org>2020-12-09 22:25:31 +0100
committerThomas Kemmer <tkemmer@computer.org>2020-12-09 23:38:17 +0100
commitca648b68fc40fe2a9eef8b469d0d130a03611f40 (patch)
tree67cc5b991de0a4d15cd22f2120b7a82e0a0a6d83
parente07d8ecb3b346ae90940e531d9ddc1565da72cd2 (diff)
downloadcachetools-ca648b68fc40fe2a9eef8b469d0d130a03611f40.tar.gz
Fix #188: In case of a race, prefer the item already in the cache.
-rw-r--r--cachetools/decorators.py12
-rw-r--r--cachetools/func.py6
2 files changed, 9 insertions, 9 deletions
diff --git a/cachetools/decorators.py b/cachetools/decorators.py
index cbea9fc..217b9a8 100644
--- a/cachetools/decorators.py
+++ b/cachetools/decorators.py
@@ -34,12 +34,12 @@ def cached(cache, key=hashkey, lock=None):
except KeyError:
pass # key not found
v = func(*args, **kwargs)
+ # in case of a race, prefer the item already in the cache
try:
with lock:
- cache[k] = v
+ return cache.setdefault(k, v)
except ValueError:
- pass # value too large
- return v
+ return v # value too large
return functools.update_wrapper(wrapper, func)
return decorator
@@ -78,11 +78,11 @@ def cachedmethod(cache, key=hashkey, lock=None):
except KeyError:
pass # key not found
v = method(self, *args, **kwargs)
+ # in case of a race, prefer the item already in the cache
try:
with lock(self):
- c[k] = v
+ return c.setdefault(k, v)
except ValueError:
- pass # value too large
- return v
+ return v # value too large
return functools.update_wrapper(wrapper, method)
return decorator
diff --git a/cachetools/func.py b/cachetools/func.py
index 07f45f2..0815bac 100644
--- a/cachetools/func.py
+++ b/cachetools/func.py
@@ -64,12 +64,12 @@ def _cache(cache, typed):
except KeyError:
stats[1] += 1
v = func(*args, **kwargs)
+ # in case of a race, prefer the item already in the cache
try:
with lock:
- cache[k] = v
+ return cache.setdefault(k, v)
except ValueError:
- pass # value too large
- return v
+ return v # value too large
def cache_info():
with lock: