perf(organizations): cache and instrument API responses
This commit is contained in:
59
src/organizations/cache.py
Normal file
59
src/organizations/cache.py
Normal file
@@ -0,0 +1,59 @@
|
||||
"""Cache helpers for organizations API responses."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import time
|
||||
|
||||
from django.core.cache import cache
|
||||
|
||||
ORGANIZATION_API_CACHE_PREFIX = "api:v2:organizations"
|
||||
ORGANIZATION_API_CACHE_VERSION_KEY = f"{ORGANIZATION_API_CACHE_PREFIX}:version"
|
||||
DEFAULT_ORGANIZATION_API_CACHE_VERSION = 1
|
||||
DEFAULT_ORGANIZATION_API_CACHE_TIMEOUT_SECONDS = 24 * 60 * 60
|
||||
|
||||
|
||||
def get_organization_api_cache_version() -> int:
|
||||
"""Return the current organizations API cache version."""
|
||||
version = cache.get(ORGANIZATION_API_CACHE_VERSION_KEY)
|
||||
if version is None:
|
||||
cache.add(
|
||||
ORGANIZATION_API_CACHE_VERSION_KEY,
|
||||
DEFAULT_ORGANIZATION_API_CACHE_VERSION,
|
||||
timeout=None,
|
||||
)
|
||||
version = cache.get(
|
||||
ORGANIZATION_API_CACHE_VERSION_KEY,
|
||||
DEFAULT_ORGANIZATION_API_CACHE_VERSION,
|
||||
)
|
||||
|
||||
try:
|
||||
return int(version)
|
||||
except (TypeError, ValueError):
|
||||
cache.set(
|
||||
ORGANIZATION_API_CACHE_VERSION_KEY,
|
||||
DEFAULT_ORGANIZATION_API_CACHE_VERSION,
|
||||
timeout=None,
|
||||
)
|
||||
return DEFAULT_ORGANIZATION_API_CACHE_VERSION
|
||||
|
||||
|
||||
def invalidate_organization_api_cache() -> int:
|
||||
"""
|
||||
Invalidate organizations API responses by moving them to a new key version.
|
||||
|
||||
Versioning avoids broad cache scans and works with cache backends that do not
|
||||
support pattern deletion.
|
||||
"""
|
||||
new_version = _new_cache_version()
|
||||
if cache.add(ORGANIZATION_API_CACHE_VERSION_KEY, new_version, timeout=None):
|
||||
return new_version
|
||||
|
||||
try:
|
||||
return int(cache.incr(ORGANIZATION_API_CACHE_VERSION_KEY))
|
||||
except (TypeError, ValueError, NotImplementedError):
|
||||
cache.set(ORGANIZATION_API_CACHE_VERSION_KEY, new_version, timeout=None)
|
||||
return new_version
|
||||
|
||||
|
||||
def _new_cache_version() -> int:
|
||||
return time.time_ns()
|
||||
Reference in New Issue
Block a user