Skip to content

Commit

Permalink
Add negative config key cache
Browse files Browse the repository at this point in the history
  • Loading branch information
dwrss committed Jun 9, 2024
1 parent ec8145c commit 120a91d
Showing 1 changed file with 29 additions and 2 deletions.
31 changes: 29 additions & 2 deletions botto/storage/config_storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
log = logging.getLogger(__name__)

ConfigCache = dict[str, dict[str, ConfigEntry]]
NegativeConfigKeyCache = dict[str, set[str]]


class ConfigStorage(Storage):
Expand All @@ -19,6 +20,8 @@ def __init__(self, airtable_base: str, airtable_key: str):
)
self.config_lock = asyncio.Lock()
self.config_cache: ConfigCache = {}
self.config_key_negative_cache_lock = asyncio.Lock()
self.config_key_negative_cache: NegativeConfigKeyCache = {}
self.auth_header = {"Authorization": f"Bearer {self.airtable_key}"}

async def clear_server_cache(self, server_id: str):
Expand Down Expand Up @@ -64,9 +67,18 @@ async def retrieve_config(
return server_config if not key else server_config[key]
except (StopIteration, StopAsyncIteration, KeyError):
log.info(f"No config found for Key {key} with Server ID {server_id}")
async with self.config_key_negative_cache_lock:
self.config_key_negative_cache.setdefault(str(server_id), set()).add(
key
)
return None

async def get_config(self, server_id: str | int, key: str) -> Optional[ConfigEntry]:
if (
not self.config_key_negative_cache_lock.locked()
and self.config_key_negative_cache.get(str(server_id), {}).get(key)
):
return None
await self.config_lock.acquire()
if (server_config := self.config_cache.get(str(server_id))) and (
config := server_config.get(key)
Expand All @@ -82,6 +94,21 @@ async def refresh_cache(self):
await self.config_lock.acquire()
current_cache = self.config_cache
self.config_lock.release()
for key in current_cache:
for key, entries in current_cache.items():
log.debug(f"Refreshing config for server {key}")
await self.retrieve_config(server_id=key, key=None)
for entry in entries.values():
await self.retrieve_config(server_id=key, key=entry.config_key)

log.info("Refreshing negative config key cache")
for server_id, keys in self.config_key_negative_cache.items():
keys_to_remove = []
for key in keys:
async with self.config_key_negative_cache_lock:
if await self.retrieve_config(server_id, key):
keys_to_remove.append(key)
log.debug(
f"Previously non-existent key {key} now exists for {server_id}"
)
for key in keys_to_remove:
self.config_key_negative_cache[server_id].remove(key)
log.info("Config cache refreshed")

0 comments on commit 120a91d

Please sign in to comment.