diff options
| author | 2020-05-23 11:35:19 +0200 | |
|---|---|---|
| committer | 2020-05-23 11:35:19 +0200 | |
| commit | c8a9a7713c4394556faadb432d1ed3b7ba5c103a (patch) | |
| tree | 633958a2bd85fe4f2d5ce9bf5e1074979fa0447c | |
| parent | Finish .set and .get, and add tests. (diff) | |
Finish asyncifying RedisCache methods
- All methods will now do a validation check
- Complete interface spec added to class:
  - .update
  - .clear
  - .pop
  - .to_dict
  - .length
  - .contains
  - .delete
  - .get
  - .set
| -rw-r--r-- | bot/utils/redis_cache.py | 50 | 
1 files changed, 34 insertions, 16 deletions
diff --git a/bot/utils/redis_cache.py b/bot/utils/redis_cache.py index 24f2f2e03..bd14fc239 100644 --- a/bot/utils/redis_cache.py +++ b/bot/utils/redis_cache.py @@ -50,8 +50,10 @@ class RedisCache:              return f"s|{value}"      @staticmethod -    def _from_typestring(value: str) -> ValidRedisType: -        """Turn a valid Redis type into a typestring.""" +    def _from_typestring(value: Union[bytes, str]) -> ValidRedisType: +        """Turn a typestring into a valid Redis type.""" +        if isinstance(value, bytes): +            value = value.decode('utf-8')          if value.startswith("f|"):              return float(value[2:])          if value.startswith("i|"): @@ -59,6 +61,14 @@ class RedisCache:          if value.startswith("s|"):              return value[2:] +    def _dict_from_typestring(self, dictionary: Dict) -> Dict: +        """Turns all contents of a dict into valid Redis types.""" +        return {self._from_typestring(key): self._from_typestring(value) for key, value in dictionary.items()} + +    def _dict_to_typestring(self, dictionary: Dict) -> Dict: +        """Turns all contents of a dict into typestrings.""" +        return {self._to_typestring(key): self._to_typestring(value) for key, value in dictionary.items()} +      async def _validate_cache(self) -> None:          """Validate that the RedisCache is ready to be used."""          if self.bot is None: @@ -120,41 +130,49 @@ class RedisCache:          if value is None:              return default          else: -            value = self._from_typestring(value.decode("utf-8")) +            value = self._from_typestring(value)              return value      async def delete(self, key: ValidRedisType) -> None:          """Delete an item from the Redis cache.""" -        # await self._redis.hdel(self._namespace, key) +        await self._validate_cache() +        key = self._to_typestring(key) +        return await self._redis.hdel(self._namespace, key)      async def contains(self, key: ValidRedisType) -> bool:          """Check if a key exists in the Redis cache.""" -        # return await self._redis.hexists(self._namespace, key) +        await self._validate_cache() +        key = self._to_typestring(key) +        return await self._redis.hexists(self._namespace, key)      async def items(self) -> AsyncIterator:          """Iterate all the items in the Redis cache.""" -        # data = await redis.hgetall(self.get_with_namespace(key)) -        # for item in data: -        #     yield item +        await self._validate_cache() +        data = await self._redis.hgetall(self._namespace)  # Get all the keys +        for key, value in self._dict_from_typestring(data).items(): +            yield key, value      async def length(self) -> int:          """Return the number of items in the Redis cache.""" -        # return await self._redis.hlen(self._namespace) +        await self._validate_cache() +        return await self._redis.hlen(self._namespace)      async def to_dict(self) -> Dict:          """Convert to dict and return.""" -        # return dict(self.items()) +        return {key: value async for key, value in self.items()}      async def clear(self) -> None:          """Deletes the entire hash from the Redis cache.""" -        # await self._redis.delete(self._namespace) +        await self._validate_cache() +        await self._redis.delete(self._namespace)      async def pop(self, key: ValidRedisType, default: Optional[ValidRedisType] = None) -> ValidRedisType:          """Get the item, remove it from the cache, and provide a default if not found.""" -        # value = await self.get(key, default) -        # await self.delete(key) -        # return value +        value = await self.get(key, default) +        await self.delete(key) +        return value -    async def update(self) -> None: +    async def update(self, items: Dict) -> None:          """Update the Redis cache with multiple values.""" -        # https://aioredis.readthedocs.io/en/v1.3.0/mixins.html#aioredis.commands.HashCommandsMixin.hmset_dict +        await self._validate_cache() +        await self._redis.hmset_dict(self._namespace, self._dict_to_typestring(items))  |