feat: add retry middleware with per-attempt governance orchestration

This commit is contained in:
2026-07-20 07:05:42 -04:00
parent f4853bf688
commit c3d5079d39
5 changed files with 705 additions and 0 deletions
+58
View File
@@ -0,0 +1,58 @@
"""熔断门封装: 后端故障必须报错而非放行(降级方向铁律,与 QuotaGate 同构)。"""
from __future__ import annotations
from typing import TYPE_CHECKING
from polygateway.errors import GovernanceBackendError
if TYPE_CHECKING:
from polygateway.ports import GateDecision, GateUpdate, ProviderGate
from polygateway.types import SourceConfig
class BreakerGate:
"""RetryMW 面向熔断后端的唯一入口;包装一切后端异常。"""
def __init__(self, gate: ProviderGate) -> None:
self._gate = gate
async def try_enter(self, source: SourceConfig, owner: str) -> GateDecision:
try:
return await self._gate.try_enter(source.name, owner)
except GovernanceBackendError:
raise
except Exception as exc:
raise GovernanceBackendError(f"熔断后端故障(try_enter): {exc}") from exc
async def record_success(self, entry: GateDecision) -> GateUpdate:
try:
return await self._gate.record_success(entry)
except GovernanceBackendError:
raise
except Exception as exc:
raise GovernanceBackendError(f"熔断后端故障(record_success): {exc}") from exc
async def record_failure(self, entry: GateDecision, reason: str, force_open: bool) -> GateUpdate:
try:
return await self._gate.record_failure(entry, reason, force_open)
except GovernanceBackendError:
raise
except Exception as exc:
raise GovernanceBackendError(f"熔断后端故障(record_failure): {exc}") from exc
async def release_probe(self, entry: GateDecision) -> GateUpdate:
try:
return await self._gate.release_probe(entry)
except GovernanceBackendError:
raise
except Exception as exc:
raise GovernanceBackendError(f"熔断后端故障(release_probe): {exc}") from exc
async def retry_after_s(self, sources: tuple[str, ...]) -> float:
try:
return await self._gate.retry_after_s(sources)
except GovernanceBackendError:
raise
except Exception as exc:
raise GovernanceBackendError(f"熔断后端故障(retry_after_s): {exc}") from exc