perf: website_sync 批量查询 + custom_pages origin TTL 缓存
This commit is contained in:
@@ -321,13 +321,49 @@ def _same_origin(a: str, b: str) -> bool:
|
||||
return _origin(a).rstrip("/") == _origin(b).rstrip("/")
|
||||
|
||||
|
||||
# ── TTL 缓存:origin → upstream_id(30 秒自动过期,无手动 invalidate)──
|
||||
import time as _time
|
||||
from functools import wraps as _wraps
|
||||
|
||||
def _ttl_cache(ttl_seconds: int = 30, maxsize: int = 64):
|
||||
def decorator(fn):
|
||||
cache: dict = {}
|
||||
@_wraps(fn)
|
||||
def wrapper(*args):
|
||||
key = args
|
||||
now = _time.monotonic()
|
||||
if key in cache:
|
||||
value, ts = cache[key]
|
||||
if now - ts < ttl_seconds:
|
||||
return value
|
||||
value = fn(*args)
|
||||
if len(cache) >= maxsize:
|
||||
cache.pop(next(iter(cache)))
|
||||
cache[key] = (value, now)
|
||||
return value
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
|
||||
def _find_matching_upstream(db: Session, page: CustomPage) -> Optional[Upstream]:
|
||||
page_origin = _origin(page.url)
|
||||
if not page_origin:
|
||||
return None
|
||||
for upstream in db.query(Upstream).order_by(Upstream.id).all():
|
||||
if _origin(upstream.base_url) == page_origin:
|
||||
return upstream
|
||||
upstream_id = _origin_to_upstream_id(page_origin)
|
||||
if upstream_id is None:
|
||||
return None
|
||||
return db.query(Upstream).filter(Upstream.id == upstream_id).first()
|
||||
|
||||
|
||||
@_ttl_cache(ttl_seconds=30, maxsize=64)
|
||||
def _origin_to_upstream_id(origin: str) -> Optional[int]:
|
||||
"""按 origin 查匹配的上游 ID,结果缓存 30 秒。"""
|
||||
from app.database import SessionLocal
|
||||
from app.models.upstream import Upstream
|
||||
with SessionLocal() as sess:
|
||||
for upstream in sess.query(Upstream).order_by(Upstream.id).all():
|
||||
if _origin(upstream.base_url) == origin:
|
||||
return upstream.id
|
||||
return None
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user