fix(ollama): cooldown provider health probes
Some checks failed
CD Pipeline / tests (push) Successful in 1m24s
Code Review / ai-code-review (push) Successful in 17s
CD Pipeline / build-and-deploy (push) Successful in 3m37s
CD Pipeline / post-deploy-checks (push) Has been cancelled

This commit is contained in:
Your Name
2026-05-25 12:25:32 +08:00
parent b9356ba1f4
commit 9ccf230a5f
7 changed files with 185 additions and 14 deletions

View File

@@ -1,9 +1,9 @@
"""
Lightweight in-process cooldown for noisy Ollama endpoint failures.
This does not change ADR-110 policy order. It only suppresses endpoints that
just failed for short-lived high-volume callers such as embedding/RAG, while
leaving health checks and failover status free to probe the full topology.
This does not change ADR-110 policy order. It suppresses endpoints that just
failed for short-lived callers while still returning explicit offline/cooldown
state to health and route-status surfaces.
"""
from __future__ import annotations
@@ -60,6 +60,26 @@ def is_ollama_endpoint_blocked(url: str, *, now: float | None = None) -> bool:
return True
def get_ollama_endpoint_cooldown_remaining_seconds(
url: str,
*,
now: float | None = None,
) -> float:
"""Return remaining cooldown seconds for display/debug surfaces."""
if not url:
return 0.0
current_time = time.monotonic() if now is None else now
normalized = _normalize_url(url)
blocked_until = _blocked_until_by_url.get(normalized)
if blocked_until is None:
return 0.0
remaining = blocked_until - current_time
if remaining <= 0:
_blocked_until_by_url.pop(normalized, None)
return 0.0
return remaining
def filter_ollama_urls_with_cooldown(
urls: Iterable[str],
*,

View File

@@ -29,6 +29,11 @@ import httpx
import structlog
from src.core.config import get_settings
from src.services.ollama_endpoint_circuit_breaker import (
get_ollama_endpoint_cooldown_remaining_seconds,
record_ollama_endpoint_failure,
record_ollama_endpoint_success,
)
logger = structlog.get_logger(__name__)
@@ -206,9 +211,21 @@ class OllamaHealthMonitor:
async def _run_checks(self, host: str) -> HealthReport:
"""依序執行三層檢查"""
cooldown_remaining = get_ollama_endpoint_cooldown_remaining_seconds(host)
if cooldown_remaining > 0:
return HealthReport(
status=HealthStatus.OFFLINE,
host=host,
reason=(
"recent_endpoint_failure_cooldown:"
f"{cooldown_remaining:.0f}s"
),
)
# 層 1連通性
connectivity_ok = await self._check_connectivity(host)
if not connectivity_ok:
record_ollama_endpoint_failure(host)
return HealthReport(
status=HealthStatus.OFFLINE,
host=host,
@@ -217,6 +234,7 @@ class OllamaHealthMonitor:
# 層 2推理測試
report = await self._check_inference(host)
record_ollama_endpoint_success(host)
return report
async def _check_connectivity(self, host: str) -> bool: