fix: reject REDIS_CACHE_TTL<=0 (kill implicit never-expire)
This commit is contained in:
@@ -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 工程配置)
|
||||||
|
|||||||
@@ -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 响应缓存。
|
||||||
|
|
||||||
|
|||||||
@@ -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 缓存不可用,诊断降级为无缓存模式")
|
||||||
|
|||||||
@@ -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 缓存不可用,降级为无缓存模式")
|
||||||
|
|||||||
@@ -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
|
||||||
Reference in New Issue
Block a user