async def read(self, device_id: str): key = BLOCK_STORE_KEY.format(id=device_id) data = [] try: self.key = None self._ready_event.clear() if not self.volatile: resp = await http.session(self.app).post(f'{STORE_URL}/get', json={ 'id': key, 'namespace': NAMESPACE, }) self.key = key data = (await resp.json())['value'].get('data', []) LOGGER.info(f'{self} Read {len(data)} blocks') except asyncio.CancelledError: # pragma: no cover raise except Exception as ex: warnings.warn(f'{self} read error {strex(ex)}') finally: # Clear -> load from database -> merge defaults TwinKeyDict.clear(self) for obj in data: TwinKeyDict.__setitem__(self, obj['keys'], obj['data']) for obj in self._defaults: with suppress(TwinKeyError): if obj['keys'] not in self: self.__setitem__(obj['keys'], obj['data']) self._ready_event.set()
async def read(self, document: str): data = [] try: self.rev = None self.document = None self._ready_event.clear() if not self.volatile: client = couchdb_client.get_client(self.app) self.rev, data = await client.read(DB_NAME, document, []) self.document = document LOGGER.info( f'{self} Read {len(data)} blocks. Rev = {self.rev}') except asyncio.CancelledError: # pragma: no cover raise except Exception as ex: warnings.warn(f'{self} read error {type(ex).__name__}({ex})') finally: # Clear -> load from database -> merge defaults TwinKeyDict.clear(self) for obj in data: TwinKeyDict.__setitem__(self, obj['keys'], obj['data']) for obj in self._defaults: with suppress(TwinKeyError): if obj['keys'] not in self: self.__setitem__(obj['keys'], obj['data']) self._ready_event.set()
def __init__(self, app: web.Application, defaults: List[dict]): FlushedStore.__init__(self, app) TwinKeyDict.__init__(self) self.key: str = None self._defaults = defaults self._ready_event: asyncio.Event = None self.clear() # inserts defaults
def __init__(self, app: web.Application, defaults: list[types.StoreEntry]): self: TwinKeyDict[str, int, dict] FlushedStore.__init__(self, app) TwinKeyDict.__init__(self) self.key: str = None self._defaults = defaults self._ready_event: asyncio.Event = None self.clear() # inserts defaults
def _find_nid( self, store: twinkeydict.TwinKeyDict, sid: str, input_type: str, ) -> int: if sid is None: return 0 if isinstance(sid, int) or sid.isdigit(): return int(sid) try: return store.right_key(sid) except KeyError: raise exceptions.UnknownId( f'No numeric ID matching [sid={sid},type={input_type}] found in store' )
def _find_sid( self, store: twinkeydict.TwinKeyDict, nid: int, input_type: str, ) -> str: if nid is None or nid == 0: return None if isinstance(nid, str): raise exceptions.DecodeException( f'Expected numeric ID, got string "{nid}"') try: sid = store.left_key(nid) except KeyError: # If service ID not found, randomly generate one sid = self._assign_id(input_type) store[sid, nid] = dict() return sid
def clear(self): TwinKeyDict.clear(self) for obj in self._defaults: self.__setitem__(obj['keys'], obj['data'])
def __delitem__(self, keys): TwinKeyDict.__delitem__(self, keys) self.set_changed()
def __setitem__(self, keys, item): TwinKeyDict.__setitem__(self, keys, item) self.set_changed()
def setup(app: web.Application): app['block_cache'] = TwinKeyDict()
def rename(cache: TwinKeyDict, existing: str, desired: str): block = cache.get((existing, None)) if block: # pragma: no cover del cache[existing, None] block['id'] = desired cache[desired, block['nid']] = block
def set_all(cache: TwinKeyDict, blocks: List[dict]): cache.clear() for block in blocks: cache[block['id'], block['nid']] = block
def delete_all(cache: TwinKeyDict): cache.clear()
def get(cache: TwinKeyDict, ids: dict) -> Optional[dict]: return cache.get((ids.get('id'), ids.get('nid')))