1# coding=utf-8 2 3from __future__ import absolute_import 4import datetime 5import threading 6 7lock = threading.Lock() 8 9 10class TempIntent(object): 11 timeout = 1000 # milliseconds 12 store = None 13 14 def __init__(self, timeout=1000, store=None): 15 self.timeout = timeout 16 if store is None: 17 raise NotImplementedError 18 19 self.store = store 20 21 def get(self, kind, *keys): 22 with lock: 23 # iter all requested keys 24 for key in keys: 25 hit = False 26 27 # skip key if invalid 28 if not key: 29 continue 30 31 # valid kind? 32 if kind in self.store: 33 now = datetime.datetime.now() 34 key = str(key) 35 36 # iter all known kinds (previously created) 37 for known_key in self.store[kind].keys(): 38 # may need locking, for now just play it safe 39 data = self.store[kind].get(known_key, {}) 40 ends = data.get("timeout") 41 if not ends: 42 continue 43 44 timed_out = False 45 if now > ends: 46 timed_out = True 47 48 # key and kind in storage, and not timed out = hit 49 if known_key == key and not timed_out: 50 hit = True 51 52 if timed_out: 53 try: 54 del self.store[kind][key] 55 except: 56 continue 57 58 if hit: 59 return True 60 return False 61 62 def resolve(self, kind, key): 63 with lock: 64 if kind in self.store and key in self.store[kind]: 65 del self.store[kind][key] 66 return True 67 return False 68 69 def set(self, kind, key, data=None, timeout=None): 70 with lock: 71 if kind not in self.store: 72 self.store[kind] = {} 73 74 key = str(key) 75 self.store[kind][key] = { 76 "data": data, 77 "timeout": datetime.datetime.now() + datetime.timedelta(milliseconds=timeout or self.timeout) 78 } 79 80 def has(self, kind, key): 81 with lock: 82 if kind not in self.store: 83 return False 84 return key in self.store[kind] 85 86 def cleanup(self): 87 now = datetime.datetime.now() 88 clear_all = False 89 for kind, info in self.store.items(): 90 for key, intent_data in info.items(): 91 # legacy intent data, clear everything 92 if not isinstance(intent_data, dict): 93 clear_all = True 94 continue 95 96 if now > intent_data["timeout"]: 97 del self.store[kind][key] 98 if clear_all: 99 self.store.clear() 100 101 self.store.save() 102 103