hy-app-monitor/core/cache.py

52 lines
1.5 KiB
Python

from __future__ import annotations
import threading
import time
from typing import Callable, Generic, TypeVar
# 泛型参数表示缓存中实际保存的数据类型。
T = TypeVar("T")
class TTLCache(Generic[T]):
# 初始化一个简单的 TTL 缓存。
def __init__(self, ttl_seconds: float) -> None:
# 保存缓存 TTL。
self.ttl_seconds = ttl_seconds
# 用锁保护并发访问。
self._lock = threading.Lock()
# 初始时没有缓存内容。
self._payload: T | None = None
# 初始构建时间为 0。
self._built_at = 0.0
# 按需获取缓存,过期时重新构建。
def get_or_build(self, builder: Callable[[], T]) -> T:
# 记录当前时间。
now = time.time()
# 先在锁内尝试读取缓存。
with self._lock:
# 有缓存且未过期时直接返回。
if self._payload is not None and now - self._built_at < self.ttl_seconds:
return self._payload
# 锁外构建新数据,避免长时间占锁。
payload = builder()
# 再次进入锁,把新结果写回去。
with self._lock:
self._payload = payload
self._built_at = now
# 返回新构建的结果。
return payload
# 主动清空缓存。
def clear(self) -> None:
# 在锁内重置缓存状态。
with self._lock:
self._payload = None
self._built_at = 0.0