Source code for fmn.cache.base

# SPDX-FileCopyrightText: Contributors to the Fedora Project
#
# SPDX-License-Identifier: MIT

import asyncio
import logging
from time import monotonic
from typing import TYPE_CHECKING

from cashews import cache
from cashews.formatter import get_templates_for_func
from cashews.ttl import ttl_to_seconds

from .util import cache_arg

if TYPE_CHECKING:
    from fedora_messaging.message import Message

log = logging.getLogger(__name__)


[docs]class CachedValue: """Manage a cached value.""" name = None
[docs] async def get_value(self, *args, **kwargs): # This method must be decorated with the cache decorator and be: # return await self.compute_value(*args, **kwargs) raise NotImplementedError
[docs] async def compute_value(self, *args, **kwargs): log.debug(f"Building the {self.name} cache") before = monotonic() value = await self._compute_value(*args, **kwargs) after = monotonic() duration = after - before log.debug(f"Built the {self.name} cache in %.2f seconds", duration) return value
async def _compute_value(self, *args, **kwargs): raise NotImplementedError
[docs] async def refresh(self, *args, **kwargs): cache_keys = get_templates_for_func(self.get_value) ttl_early = cache_arg("early_ttl", self.name)() if not ttl_early: return ttl_early = ttl_to_seconds(ttl_early) refreshed = False for cache_key in cache_keys: expire = await cache.get_expire(cache_key) if expire <= ttl_to_seconds(ttl_early): ttl = ttl_to_seconds(cache_arg("ttl", self.name)()) value = await self.compute_value(*args, **kwargs) await cache.set(cache_key, value=value, expire=ttl) refreshed = True return refreshed
[docs] async def invalidate(self): log.debug(f"Invalidating the {self.name} cache") cache_keys = get_templates_for_func(self.get_value) await asyncio.gather(*(cache.delete(key) for key in cache_keys))
[docs] async def invalidate_on_message(self, message: "Message"): raise NotImplementedError