This repository has been archived on 2020-03-24. You can view files and clone it, but cannot push or open issues or pull requests.
quay/util/expiresdict.py
Joseph Schorr 0ba54ed4fc Simplify the caching of service keys to hopefully avoid the not found issue
Makes accesses simpler and reduces the number of dictionaries to one, in an effort to remove race conditions
2017-05-26 13:51:48 -04:00

57 lines
1.5 KiB
Python

from datetime import datetime
class ExpiresEntry(object):
""" A single entry under a ExpiresDict. """
def __init__(self, value, expires=None):
self.value = value
self._expiration = expires
@property
def expired(self):
if self._expiration is None:
return False
return datetime.now() >= self._expiration
class ExpiresDict(object):
""" ExpiresDict defines a dictionary-like class whose keys have expiration. The rebuilder is
a function that returns the full contents of the cached dictionary as a dict of the keys
and whose values are TTLEntry's.
"""
def __init__(self, rebuilder):
self._rebuilder = rebuilder
self._items = {}
def __getitem__(self, key):
found = self.get(key)
if found is None:
raise KeyError
return found
def get(self, key, default_value=None):
# Check the cache first. If the key is found and it has not yet expired,
# return it.
found = self._items.get(key)
if found is not None and not found.expired:
return found.value
# Otherwise the key has expired or was not found. Rebuild the cache and check it again.
items = self._rebuild()
found_item = items.get(key)
if found_item is None:
return default_value
return found_item.value
def __contains__(self, key):
return self.get(key) is not None
def _rebuild(self):
items = self._rebuilder()
self._items = items
return items
def set(self, key, value, expires=None):
self._items[key] = ExpiresEntry(value, expires=expires)