diff options
| -rw-r--r-- | bot/exts/info/doc/_cog.py | 14 | ||||
| -rw-r--r-- | bot/exts/info/doc/_redis_cache.py | 17 | 
2 files changed, 25 insertions, 6 deletions
diff --git a/bot/exts/info/doc/_cog.py b/bot/exts/info/doc/_cog.py index 67a21ed72..678134f3c 100644 --- a/bot/exts/info/doc/_cog.py +++ b/bot/exts/info/doc/_cog.py @@ -36,6 +36,8 @@ FORCE_PREFIX_GROUPS = (  WHITESPACE_AFTER_NEWLINES_RE = re.compile(r"(?<=\n\n)(\s+)")  NOT_FOUND_DELETE_DELAY = RedirectOutput.delete_delay +doc_cache = DocRedisCache(namespace="Docs") +  class DocItem(NamedTuple):      """Holds inventory symbol information.""" @@ -116,7 +118,9 @@ class CachedParser:          while self._queue:              item, soup = self._queue.pop()              try: -                self._results[item] = get_symbol_markdown(soup, item) +                markdown = get_symbol_markdown(soup, item) +                await doc_cache.set_if_exists(item, markdown) +                self._results[item] = markdown              except Exception:                  log.exception(f"Unexpected error when handling {item}")              else: @@ -161,8 +165,6 @@ class CachedParser:  class DocCog(commands.Cog):      """A set of commands for querying & displaying documentation.""" -    doc_cache = DocRedisCache() -      def __init__(self, bot: Bot):          self.base_urls = {}          self.bot = bot @@ -174,7 +176,7 @@ class DocCog(commands.Cog):          self.scheduled_inventories = set()          self.bot.loop.create_task(self.init_refresh_inventory()) -        self.bot.loop.create_task(self.doc_cache.delete_expired()) +        self.bot.loop.create_task(doc_cache.delete_expired())      async def init_refresh_inventory(self) -> None:          """Refresh documentation inventory on cog initialization.""" @@ -292,12 +294,12 @@ class DocCog(commands.Cog):              return None          self.bot.stats.incr(f"doc_fetches.{symbol_info.package.lower()}") -        markdown = await self.doc_cache.get(symbol_info) +        markdown = await doc_cache.get(symbol_info)          if markdown is None:              log.debug(f"Redis cache miss for symbol `{symbol}`.")              markdown = await self.item_fetcher.get_markdown(self.bot.http_session, symbol_info)              if markdown is not None: -                await self.doc_cache.set(symbol_info, markdown) +                await doc_cache.set(symbol_info, markdown)              else:                  markdown = "Unable to parse the requested symbol." diff --git a/bot/exts/info/doc/_redis_cache.py b/bot/exts/info/doc/_redis_cache.py index c617eba49..2230884c9 100644 --- a/bot/exts/info/doc/_redis_cache.py +++ b/bot/exts/info/doc/_redis_cache.py @@ -28,6 +28,23 @@ class DocRedisCache(RedisObject):              )      @namespace_lock +    async def set_if_exists(self, item: DocItem, value: str) -> None: +        """ +        Set markdown `value` for `key` if `key` exists. + +        Keys expire after a week to keep data up to date. +        """ +        expiry_timestamp = datetime.datetime.now().timestamp() + 7 * 24 * 60 * 60 + +        with await self._get_pool_connection() as connection: +            if await connection.hexists(f"{self.namespace}:{item.package}", self.get_item_key(item)): +                await connection.hset( +                    f"{self.namespace}:{item.package}", +                    self.get_item_key(item), +                    pickle.dumps((value, expiry_timestamp)) +                ) + +    @namespace_lock      async def get(self, item: DocItem) -> Optional[str]:          """Get markdown contents for `key`."""          with await self._get_pool_connection() as connection:  |