mirror of
https://github.com/HyPnoTiiK/stream-fusion.git
synced 2026-07-29 07:22:46 +00:00
Add a two-level caching architecture for debrid service availability lookups: - L1: Redis (existing) with 10-day TTL for fast in-memory access - L2: PostgreSQL with 30-day TTL for persistent caching across Redis restarts Changes: - Add `debrid_cache` table with unique constraint on (info_hash, service) and indexes for efficient queries - Create `DebridCacheDAO` with batch get/upsert and invalidation methods - Add pgCron job to periodically clean up expired cache entries - Extend `get_availability_bulk_cached` to check PG on Redis miss, warm Redis from PG hits, and write confirmed-cached results to PG - Add `invalidate_availability_cache` method to remove false positives from both caches when NO_CACHE_VIDEO_URL is returned during playback - Integrate `db_session` dependency into playback and search views - Add retry handling to Yggflix API (3 retries, ignore Retry-After headers) and rate-limiting delay (0.3s) between consecutive queries
28 lines
1.2 KiB
Python
28 lines
1.2 KiB
Python
from typing import Optional
|
|
|
|
from sqlalchemy import BigInteger, String, UniqueConstraint
|
|
from sqlalchemy.dialects.postgresql import JSONB
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from stream_fusion.services.postgresql.base import Base
|
|
|
|
|
|
class DebridCacheModel(Base):
|
|
"""Persistent cache of debrid availability results, shared across all users.
|
|
|
|
Only confirmed-cached hashes are stored (no negative / not-cached entries).
|
|
All data stored here has been sanitised: no private tokens, no announce URLs.
|
|
"""
|
|
|
|
__tablename__ = "debrid_cache"
|
|
|
|
id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True)
|
|
info_hash: Mapped[str] = mapped_column(String(40), nullable=False)
|
|
service: Mapped[str] = mapped_column(String(20), nullable=False) # e.g. 'realdebrid', 'alldebrid'
|
|
cached_data: Mapped[Optional[dict]] = mapped_column(JSONB, nullable=True) # sanitised file metadata
|
|
checked_at: Mapped[int] = mapped_column(BigInteger, nullable=False) # Unix timestamp
|
|
expires_at: Mapped[int] = mapped_column(BigInteger, nullable=False) # Unix timestamp
|
|
|
|
__table_args__ = (
|
|
UniqueConstraint("info_hash", "service", name="uq_debrid_cache_hash_service"),
|
|
)
|