Repository navigation
feat: retry with exponential backoff and circuit breaker for price oracle calls (Closes #550) - #571
Closed
Simultech369 wants to merge 1 commit into
Closed
Simultech369 wants to merge 1 commit into
Simultech369 wants to merge 1 commit into
Conversation
…racle calls (StableRoute-Org#550) Closes StableRoute-Org#550. Implements a resilient upstream price oracle architecture featuring: - Bounded retry attempts with exponential backoff, max delay ceiling, and full jitter randomization to prevent stampedes - Full 3-state circuit breaker (CLOSED -> OPEN -> HALF_OPEN -> CLOSED) with configurable failure thresholds and cooldown - Fast-fail protection with typed 503 upstream_unavailable error when breaker is OPEN - Intelligent error classification: retries transient network blips, 5xx, and 429; fails fast on 4xx/validation errors - Idempotency guards: non-idempotent operations skip retries to prevent duplicate side effects - Per-dependency circuit breaker isolation via CircuitBreakerRegistry - Prometheus metrics exposition for circuit breaker states, failures, successes, and short-circuits - Dynamic runtime configuration tuning via PATCH /api/v1/config - Status and rate inspection routes (GET /api/v1/oracle/status, GET /api/v1/oracle/rate/:source/:destination) - Full OpenAPI 3.0.3 specification coverage and architecture documentation
Contributor
|
Closing as part of a repository reset; new issues will be opened shortly. Thanks for contributing! |
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
Closes #550.
This pull request delivers a production-grade resilience layer for upstream price oracle and external rate lookups, resolving cascading failure vulnerabilities, stampedes, and unbounded hanging requests.
Core Enhancements
Exponential Backoff with Full Jitter (
src/oracle/retry.ts):maxAttempts(default 3: 1 initial attempt + 2 retries).maxDelayMs), multiplier, and injectable sleep timer for testing.Per-Dependency Circuit Breaker (
src/oracle/circuitBreaker.ts):CLOSED->OPEN->HALF_OPEN->CLOSED.failureThreshold(default 5), the breaker entersOPENand immediately rejects subsequent traffic with typedCircuitBreakerOpenError/ HTTP 503upstream_unavailablewithout making network calls.cooldownMs(default 30s) elapses, transitions toHALF_OPENand admits a single probe request. Success closes the circuit; failure immediately reopens it.circuitBreakerRegistry. An outage in one upstream oracle never trips or impacts another.Intelligent Error Classification & Idempotency:
ECONNRESET,ETIMEDOUT,ECONNREFUSED,ENOTFOUND,EAI_AGAIN,EPIPE), HTTP 5xx responses, and HTTP 429 rate limits.isIdempotent: false) bypass retries completely to prevent duplicate side effects.API Endpoints & Runtime Tuning (
src/index.ts):GET /api/v1/oracle/status: Query breaker state and metrics (per dependency or globally).GET /api/v1/oracle/rate/:source/:destination: Exchange rate lookups guarded by the retry and circuit breaker pipeline.PATCH /api/v1/config: Live dynamic tuning oforacleRetryAttempts,oracleBackoffBaseMs,oracleBreakerThreshold, andoracleBreakerCooldownMs.Prometheus Metrics Exposition (
GET /api/v1/metrics):stableroute_circuit_breaker_state{dependency="..."}(0=CLOSED, 1=HALF_OPEN, 2=OPEN).stableroute_circuit_breaker_failures_total{dependency="..."}.stableroute_circuit_breaker_successes_total{dependency="..."}.stableroute_circuit_breaker_short_circuits_total{dependency="..."}.OpenAPI 3.0.3 Spec & Technical Documentation:
src/openapi.tspassing the router drift guard test.docs/price-oracle-resilience.md.Edge Cases Covered & Tested
All 5 required edge cases are covered with dedicated tests in
src/__tests__/circuitBreaker.test.tsandsrc/__tests__/oracleIntegration.test.ts:CLOSEDtoOPENand subsequent calls fail fast with typedupstream_unavailable.HALF_OPEN; probe success transitions back toCLOSED.maxAttemptsis reached.OPEN.Verification Results
npm run lint: Passed with 0 errors.npm run build: Passed with 0 errors (tscclean).npm test: 37 / 37 test suites passed, 1004 / 1004 tests passed.