# coding=utf-8 from __future__ import absolute_import import datetime import threading lock = threading.Lock() class TempIntent(object): timeout = 1000 # milliseconds store = None def __init__(self, timeout=1000, store=None): self.timeout = timeout if store is None: raise NotImplementedError self.store = store def get(self, kind, *keys): with lock: # iter all requested keys for key in keys: hit = False # skip key if invalid if not key: continue # valid kind? if kind in self.store: now = datetime.datetime.now() key = str(key) # iter all known kinds (previously created) for known_key in self.store[kind].keys(): # may need locking, for now just play it safe data = self.store[kind].get(known_key, {}) ends = data.get("timeout") if not ends: continue timed_out = False if now > ends: timed_out = True # key and kind in storage, and not timed out = hit if known_key == key and not timed_out: hit = True if timed_out: try: del self.store[kind][key] except: continue if hit: return True return False def resolve(self, kind, key): with lock: if kind in self.store and key in self.store[kind]: del self.store[kind][key] return True return False def set(self, kind, key, data=None, timeout=None): with lock: if kind not in self.store: self.store[kind] = {} key = str(key) self.store[kind][key] = { "data": data, "timeout": datetime.datetime.now() + datetime.timedelta(milliseconds=timeout or self.timeout) } def has(self, kind, key): with lock: if kind not in self.store: return False return key in self.store[kind] def cleanup(self): now = datetime.datetime.now() clear_all = False for kind, info in self.store.items(): for key, intent_data in info.items(): # legacy intent data, clear everything if not isinstance(intent_data, dict): clear_all = True continue if now > intent_data["timeout"]: del self.store[kind][key] if clear_all: self.store.clear() self.store.save()