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()
예제 #2
0
    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
예제 #5
0
    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'
            )
예제 #6
0
    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
예제 #7
0
 def clear(self):
     TwinKeyDict.clear(self)
     for obj in self._defaults:
         self.__setitem__(obj['keys'], obj['data'])
예제 #8
0
 def __delitem__(self, keys):
     TwinKeyDict.__delitem__(self, keys)
     self.set_changed()
예제 #9
0
 def __setitem__(self, keys, item):
     TwinKeyDict.__setitem__(self, keys, item)
     self.set_changed()
예제 #10
0
def setup(app: web.Application):
    app['block_cache'] = TwinKeyDict()
예제 #11
0
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
예제 #12
0
def set_all(cache: TwinKeyDict, blocks: List[dict]):
    cache.clear()
    for block in blocks:
        cache[block['id'], block['nid']] = block
예제 #13
0
def delete_all(cache: TwinKeyDict):
    cache.clear()
예제 #14
0
def get(cache: TwinKeyDict, ids: dict) -> Optional[dict]:
    return cache.get((ids.get('id'), ids.get('nid')))