fix: reject REDIS_CACHE_TTL<=0 (kill implicit never-expire)

This commit is contained in:
2026-07-16 05:25:36 -04:00
parent 564c92a043
commit 7cc6aa5b23
5 changed files with 46 additions and 6 deletions
+1
View File
@@ -46,6 +46,7 @@ LLM_CIRCUIT_BREAKER_COOLDOWN=60
LLM_TTFT_TIMEOUT=30 LLM_TTFT_TIMEOUT=30
LLM_INTER_TOKEN_TIMEOUT=15 LLM_INTER_TOKEN_TIMEOUT=15
LLM_RETRY_MAX_DELAY=30.0 LLM_RETRY_MAX_DELAY=30.0
# 正整数秒,禁止 0(0 会被拒绝启动);训练场景建议 >= 单次训练时长
REDIS_CACHE_TTL=86400 REDIS_CACHE_TTL=86400
# 建树批量并行:全局 VLM/LLM 在途调用上限(Spec-2 工程配置) # 建树批量并行:全局 VLM/LLM 在途调用上限(Spec-2 工程配置)
+20
View File
@@ -12,6 +12,26 @@ from loguru import logger
from core.types import LLMResponse from core.types import LLMResponse
def _resolve_cache_ttl(ttl: int) -> int:
"""校验 Redis 缓存 TTL:必须为正整数(消灭 0=永不过期 的隐式语义)。
Args:
ttl: 待校验的 TTL 秒数。
Returns:
校验通过的正整数 TTL。
Raises:
ValueError: ttl <= 0。
"""
if ttl <= 0:
raise ValueError(
f"REDIS_CACHE_TTL 必须为正整数秒,实际 {ttl}"
"训练场景建议 >= 单次训练时长(如 86400)。"
)
return ttl
class RedisResponseCache: class RedisResponseCache:
"""基于 Redis 的 LLM 响应缓存。 """基于 Redis 的 LLM 响应缓存。
+5 -3
View File
@@ -248,13 +248,15 @@ def _build_redis_cache(settings: Any) -> Any | None:
"""按 .env redis_url 构建响应缓存(不可用则降级 None,与 main 一致)。""" """按 .env redis_url 构建响应缓存(不可用则降级 None,与 main 一致)。"""
if not settings.redis_url: if not settings.redis_url:
return None return None
from adapters.redis_cache import RedisResponseCache, _resolve_cache_ttl
# 配置校验 fail-loud(不属于 Redis 连接故障,不得被下方降级 except 吞掉)
ttl_s = _resolve_cache_ttl(settings.redis_cache_ttl)
try: try:
import redis.asyncio as aioredis import redis.asyncio as aioredis
from adapters.redis_cache import RedisResponseCache
redis_client = aioredis.from_url(settings.redis_url, decode_responses=True) redis_client = aioredis.from_url(settings.redis_url, decode_responses=True)
ttl_s = settings.redis_cache_ttl if settings.redis_cache_ttl > 0 else None
return RedisResponseCache(redis=redis_client, ttl_s=ttl_s) return RedisResponseCache(redis=redis_client, ttl_s=ttl_s)
except Exception: except Exception:
logger.warning("Redis 缓存不可用,诊断降级为无缓存模式") logger.warning("Redis 缓存不可用,诊断降级为无缓存模式")
+4 -3
View File
@@ -84,13 +84,14 @@ def _build_adapters(settings: InfraSettings, embed_cfg: dict) -> _Adapters:
cache = None cache = None
if settings.redis_url: if settings.redis_url:
from adapters.redis_cache import RedisResponseCache, _resolve_cache_ttl
# 配置校验 fail-loud(不属于 Redis 连接故障,不得被下方降级 except 吞掉)
ttl_s = _resolve_cache_ttl(settings.redis_cache_ttl)
try: try:
import redis.asyncio as aioredis import redis.asyncio as aioredis
from adapters.redis_cache import RedisResponseCache
redis_client = aioredis.from_url(settings.redis_url, decode_responses=True) redis_client = aioredis.from_url(settings.redis_url, decode_responses=True)
ttl_s = settings.redis_cache_ttl if settings.redis_cache_ttl > 0 else None
cache = RedisResponseCache(redis=redis_client, ttl_s=ttl_s) cache = RedisResponseCache(redis=redis_client, ttl_s=ttl_s)
except Exception: except Exception:
logger.warning("Redis 缓存不可用,降级为无缓存模式") logger.warning("Redis 缓存不可用,降级为无缓存模式")
+16
View File
@@ -0,0 +1,16 @@
"""工程配置校验单元测试(Redis 缓存 TTL fail-loud)。"""
from __future__ import annotations
import pytest
def test_redis_cache_ttl_zero_rejected() -> None:
"""REDIS_CACHE_TTL<=0 必须启动即报错,消灭'0=永不过期'隐式语义。"""
from adapters.redis_cache import _resolve_cache_ttl
with pytest.raises(ValueError, match="REDIS_CACHE_TTL"):
_resolve_cache_ttl(0)
with pytest.raises(ValueError, match="REDIS_CACHE_TTL"):
_resolve_cache_ttl(-1)
assert _resolve_cache_ttl(86400) == 86400