fix(proxy): wire circuit breakers into the live request path#1
Merged
Conversation
The three-state CircuitBreaker class existed but was dead code: the proxy passed an empty Map to HealthMonitor, isProviderUsable() had no callers, and request outcomes never fed any breaker. - createProxyServer now builds one CircuitBreaker per provider, shared by the request path and the health monitor (exposed via app.locals for lifecycle/tests, plus a deps param for provider injection in tests) - /v1/chat/completions gates the primary on allowRequest() and records success/failure on every outcome (non-stream and stream) - fallback chain skips the just-failed primary (previously retried it immediately) and skips providers whose breaker is open - HealthProbe now calls the real provider interface (getProviderId()/ healthCheck()); it previously called provider.chat()/provider.id which do not exist, so every probe reported 'down' - fix off-by-one: breaker closes after successThreshold successes in half-open, not successThreshold+1 Integration tests: breaker opens after N failures and blocks traffic, then recovers through half-open after cooldown. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题
三态
CircuitBreaker类实现完整但在服务路径上是死代码:createProxyServer传给HealthMonitor的断路器 map 是空new Map(),全项目从未实例化过断路器isProviderUsable()没有任何调用者HealthProbe调用的provider.chat()/provider.id在真实 provider 上不存在,所有探测永远报 down修复
CircuitBreaker实例,请求路径与健康监控共享;通过app.locals暴露(生命周期管理 + 测试),createProxyServer增加可选deps参数支持注入/v1/chat/completions主 provider 先过allowRequest()闸门,每次成败调用recordSuccess/recordFailure(流式路径同样接入)HealthProbe改为调用 provider 真实存在的healthCheck()(自带各家 health-check 模型)+ 超时竞速>→>=,与文档语义一致测试
tests/proxy-breaker.test.ts集成测试:注入必失败的假 provider,断言 3 次失败后断路器 open、第 4 次请求返回 503 且不再调用 provider、冷却后半开放行并恢复tsc --noEmit干净🤖 Generated with Claude Code