48 lines
1.6 KiB
Python
48 lines
1.6 KiB
Python
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import asyncio
|
||
|
|
import copy
|
||
|
|
import time
|
||
|
|
|
||
|
|
from live_prototype import build_live_prototype_payload
|
||
|
|
from settings import Settings
|
||
|
|
|
||
|
|
|
||
|
|
class PrototypePayloadCache:
|
||
|
|
def __init__(self) -> None:
|
||
|
|
self._payload: dict[str, object] | None = None
|
||
|
|
self._expires_at = 0.0
|
||
|
|
self._lock = asyncio.Lock()
|
||
|
|
|
||
|
|
async def get(self, settings: Settings) -> dict[str, object]:
|
||
|
|
if settings.forgejo_cache_ttl_seconds <= 0:
|
||
|
|
return copy.deepcopy(await self._build_public_payload(settings))
|
||
|
|
|
||
|
|
now = time.monotonic()
|
||
|
|
if self._payload is not None and now < self._expires_at:
|
||
|
|
return copy.deepcopy(self._payload)
|
||
|
|
|
||
|
|
async with self._lock:
|
||
|
|
now = time.monotonic()
|
||
|
|
if self._payload is not None and now < self._expires_at:
|
||
|
|
return copy.deepcopy(self._payload)
|
||
|
|
|
||
|
|
payload = await self._build_public_payload(settings)
|
||
|
|
self._payload = copy.deepcopy(payload)
|
||
|
|
self._expires_at = time.monotonic() + settings.forgejo_cache_ttl_seconds
|
||
|
|
return copy.deepcopy(self._payload)
|
||
|
|
|
||
|
|
def invalidate(self) -> None:
|
||
|
|
self._payload = None
|
||
|
|
self._expires_at = 0.0
|
||
|
|
|
||
|
|
async def _build_public_payload(self, settings: Settings) -> dict[str, object]:
|
||
|
|
read_token = settings.forgejo_token
|
||
|
|
auth_source = "server" if read_token else "none"
|
||
|
|
return await build_live_prototype_payload(
|
||
|
|
settings,
|
||
|
|
forgejo_token=read_token,
|
||
|
|
auth_source=auth_source,
|
||
|
|
session_user=None,
|
||
|
|
)
|