Created
March 11, 2016 01:46
-
-
Save lucidfrontier45/cb72db855a7193322e39 to your computer and use it in GitHub Desktop.
Python Dict with expiry
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import time | |
| from collections import UserDict | |
| from threading import Lock, Event, Thread | |
| from functional import seq | |
| # <http://stackoverflow.com/questions/22498038/improve-current-implementation-of-a-setinterval-python/22498708#22498708> | |
| def set_interval(interval, func, *args): | |
| stopped = Event() | |
| def loop(): | |
| while not stopped.wait(interval): # the first call is in `interval` secs | |
| func(*args) | |
| Thread(target=loop).start() | |
| return stopped.set | |
| class TimeoutableDict(UserDict): | |
| def __init__(self, initialdata=None, lifetime=300): | |
| self._lifetime = lifetime | |
| self._lock = Lock() | |
| self._timestamps = dict() | |
| UserDict.__init__(self, initialdata) | |
| self._cancel = set_interval(lifetime, self.clear_expired_items) | |
| def __del__(self): | |
| self._cancel() | |
| def __setitem__(self, key, value): | |
| now = time.time() | |
| with self._lock: | |
| self._timestamps[key] = now | |
| self.data[key] = value | |
| def __getitem__(self, key): | |
| now = time.time() | |
| with self._lock: | |
| if key in self.data: | |
| self._timestamps[key] = now | |
| return self.data[key] | |
| else: | |
| return None | |
| def __delitem__(self, key): | |
| with self._lock: | |
| if key in self.data: | |
| self._timestamps.__delitem__(key) | |
| self.data.__delitem__(key) | |
| def clear_expired_items(self): | |
| now = time.time() | |
| def _clean_item(key): | |
| self._timestamps.__delitem__(key) | |
| self.data.__delitem__(key) | |
| with self._lock: | |
| keys_to_remove = seq(self.data.keys()) \ | |
| .filter(lambda k: now - self._timestamps[k] > self._lifetime) \ | |
| .to_list() | |
| seq(keys_to_remove).for_each(_clean_item) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment