File size: 1,910 Bytes
af5af97
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fd65b82
af5af97
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
"""
Redis-backed cache for EngineeringReport results, keyed by
(github_url, head_sha). Best-effort: any Redis error is logged and
treated as a cache miss / no-op write, never raised to callers.
"""
from functools import lru_cache

import redis

from app.core.config import get_settings
from app.core.logger import get_logger
from app.models.report import EngineeringReport

logger = get_logger(__name__)


@lru_cache()
def get_redis_client() -> redis.Redis:
    settings = get_settings()
    return redis.Redis.from_url(settings.redis_url, decode_responses=True)


def _cache_key(github_url: str, head_sha: str) -> str:
    return f"analysis:{github_url}:{head_sha}"


def get_cached_report(github_url: str, head_sha: str) -> EngineeringReport | None:
    """Return a cached EngineeringReport, or None on a miss or Redis error."""
    try:
        client = get_redis_client()
        raw = client.get(_cache_key(github_url, head_sha))
    except Exception as exc:
        logger.warning("Cache read failed", extra={"error": str(exc)})
        return None

    if raw is None:
        return None

    try:
        return EngineeringReport.model_validate_json(str(raw))
    except Exception as exc:
        logger.warning("Cached report failed to deserialize", extra={"error": str(exc)})
        return None


def set_cached_report(github_url: str, head_sha: str, report: EngineeringReport) -> None:
    """Best-effort write of an EngineeringReport to the cache with a TTL."""
    try:
        settings = get_settings()
        client = get_redis_client()
        client.set(
            _cache_key(github_url, head_sha),
            report.model_dump_json(),
            ex=settings.cache_ttl_seconds,
        )
    except Exception as exc:
        logger.warning("Cache write failed", extra={"error": str(exc)})


def _clear_redis_client_cache() -> None:  # test helper only
    get_redis_client.cache_clear()