feat: per-endpoint circuit breaker for /api/comments downstream calls (#613) - #724
Merged
greatest0fallt1me merged 3 commits intoJul 29, 2026
Conversation
…alls
Implements a CLOSED/OPEN/HALF_OPEN circuit breaker in src/lib/circuitBreaker.ts
and integrates two named breaker instances into src/routes/comments.ts:
commentsDbBreaker — guards listMarketComments (Postgres via Drizzle)
commentsOutboundBreaker — guards fetchWithCorrelationId (outbound HTTP)
Behaviour:
- CLOSED: calls pass through; failures are counted in a 60-second rolling window
- OPEN: all calls fast-fail with HTTP 503 { error: { code: 'service_unavailable' } }
- HALF_OPEN: a single probe is allowed after 30 s; success → CLOSED, failure → OPEN
- Both breakers are exported from comments.ts for test-time manipulation
Adds 31 focused tests in tests/commentsCircuitBreaker.test.ts:
- State machine tests: CLOSED/OPEN/HALF_OPEN transitions, rolling window,
concurrent probe guard, reset()
- Route integration tests: 503 on open DB breaker, DB errors trip the breaker,
503 on open outbound breaker, fetch errors trip the breaker
No regressions: all 13 existing market-comments tests continue to pass.
Closes Predictify-org#613
|
@thelmaoffiong Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
Contributor
|
Merged into main via admin resolver (-X theirs). |
Contributor
|
All checks green — merging. Nice job! 🚀 |
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.
Summary
Implements a per-endpoint circuit breaker around the two downstream calls made by
/api/comments, as required by issue #613. When a breaker trips, the route responds with HTTP 503 immediately rather than queuing requests behind a failing dependency.New file:
src/lib/circuitBreaker.tsA generic, reusable
CircuitBreakerclass with the classic three-state machine:failureThresholdfailures accumulate withinwindowMs.CircuitOpenError. AfterresetTimeoutMselapses the breaker moves to HALF_OPEN.Also exports
CircuitOpenError— callers checkinstanceof CircuitOpenErrorto distinguish a tripped breaker from a genuine downstream error.Default configuration:
failureThreshold= 5windowMs= 60 000 ms (1 min rolling window)resetTimeoutMs= 30 000 ms (probe after 30 s)Updated:
src/routes/comments.tsTwo module-level breaker singletons (exported for tests):
Both downstream calls are now wrapped:
listMarketComments()— Postgres via DrizzlecommentsDbBreakerfetchWithCorrelationId()— optional outbound HTTPcommentsOutboundBreakerWhen either breaker is OPEN the route returns:
Tests:
tests/commentsCircuitBreaker.test.ts(31 tests)CircuitBreaker state machine (15 tests)
reset()restores CLOSED stateRoute integration (12 tests)
commentsDbBreakeris OPENlistMarketCommentswhen breaker is OPENcommentsOutboundBreakeris OPENfetchWithCorrelationIdwhen breaker is OPENoutboundUrlis absentCircuitOpenError class (4 tests)
All 13 existing market-comments tests continue to pass (no regressions).
Closes #613