Repository navigation
refactor(demo-26): S14 PR 1 — failure modes on resilience libraries - #80
Merged
Merged
Conversation
…e FT, MEHR 10.10.0, tenacity, purgatory, x/sync)
…ts again (S14 D1, 20 -> 22 checks)
…nce4j (S14) The hand-written CircuitBreaker, retry loop and Semaphore are replaced by @CIRCUITBREAKER (fallbackMethod), @Retry and @bulkhead on a BackendClient bean, configured in application.properties: 5 failures open the breaker for 10 s, 2 trial successes close it; 3 attempts from 100 ms doubling with 50% jitter; 5 concurrent calls, the next refused at once and answered with 429. /breaker-state is {name, state} plus Resilience4j's own metrics (D2).
…ult Tolerance (S14) @Retry + @ExponentialBackoff, @CIRCUITBREAKER + @CircuitBreakerName + @fallback (the fallback takes the cause) and @bulkhead on a Backend bean replace the hand-written CircuitBreaker, retry loop and Semaphore. A full bulkhead's BulkheadException is mapped to 429; /breaker-state reads CircuitBreakerMaintenance (D2). The backend moves to /process with X-Deadline-Ms and answers a too-small budget with 200, as in the other languages.
… v8 pipelines (S14) Named pipelines registered with AddResiliencePipeline use the HTTP strategy options from Microsoft.Extensions.Http.Resilience 10.10.0: retry (2 retries, exponential from 100 ms with jitter), circuit breaker (5 of 5 failures open it for 10 s; state through CircuitBreakerStateProvider), timeout (2 s) and a concurrency limiter of 5 with no queue (429 when full). Polly.Extensions and Polly.RateLimiting are pinned to 8.8.0, since the resilience package only sets a >= 8.4.2 floor.
…(S14) AsyncRetrying (3 attempts, exponential jitter from 100 ms to 2 s) replaces the retry loop; pybreaker (fail_max 5, reset_timeout 10, success_threshold 2) wraps the awaited call through its calling() context manager in place of the hand-written class. One httpx.AsyncClient opened in the lifespan replaces a client per request; the bulkhead semaphore answers 429 when full instead of racing wait_for.
…and responses aligned (S14) gobreaker keeps the breaker and backoff the retry; MaxRequests 2 so two trial successes close it, as in the other languages, and the retry starts at 100 ms. The bulkhead is a semaphore.Weighted with TryAcquire (429 when full) instead of a buffered channel returning 503. The breaker endpoint answers with the shared fallback body (reason circuit_open | upstream_<status> | upstream_unreachable, plus the breaker state) and /breaker-state carries the name (D2). The backend moves to /process with X-Deadline-Ms and answers a too-small budget with 200.
…ient (S14 D3) No maintained C++ resilience library is on ConanCenter, so the breaker and the bulkhead stay hand-written, now compact: 5 failures open the breaker for 10 s, 2 trial successes close it, and the fallback reports circuit_open, upstream_<status> or upstream_unreachable like the other languages. Every handler is a coroutine: backend calls co_await HttpClient::sendRequestCoro and the retry delay co_awaits sleepCoro, so no event-loop thread blocks (the old libcurl calls and sleep_for did). The full bulkhead answers 429 (was 503); the unused retry_with_backoff helper is gone, and so is libcurl (lock cleaned with --lockfile-clean). The backend's slow mode answers from a 5 s timer instead of sleeping on the event loop.
…eld-initializers)
…based examples (S14) The timeout, retry and circuit-breaker codetabs are now condensed excerpts of examples/26 in all six languages (Resilience4j, SmallRye Fault Tolerance, Polly v8 pipelines, tenacity and pybreaker, cenkalti/backoff and gobreaker, and the C++ coroutine version) instead of illustrative PaymentService snippets. The READMEs name the libraries, the 429 bulkhead and the Drogon HttpClient.
… of examples/26 in all six decks (S14) The 18 code slides showed illustrative PaymentService/QuoteService code (and in C++ a gRPC deadline and an atomic breaker); they now carry condensed excerpts of the library-based examples with matching chips and notes: Resilience4j, SmallRye Fault Tolerance, Polly v8 pipelines, tenacity and pybreaker, cenkalti/backoff and gobreaker, and the C++ coroutine version. Edit files Spring.fix8, Quarkus.fix7, DotNet.fix9, Python.fix7, Go.fix5, Cpp.fix5; all 18 slides rendered and read, deck_fit 0.
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.
S14 PR 1 of 4 (plan:
_plans/s14-resilience-plan.md, steps 0 and 1). Example 26's breaker, retry and bulkhead move from hand-written code to each stack's resilience library.@CircuitBreaker+ fallback method@Retry@Bulkhead@CircuitBreaker+@Fallback@Retry+@ExponentialBackoff@BulkheadHttpRetryStrategyOptionscalling()AsyncRetryingasyncio.Semaphorex/sync/semaphoreTryAcquiresleepCorostd::counting_semaphoreContract changes (user decisions D1, D2):
verify.shadds a saturation check and a recovery check, taking 26 from 20 to 22 checks./breaker-stateis{name, state}plus whatever metrics the library exposes; the state isclosed,openorhalf-open./processwithX-Deadline-Ms, like the other four.Clean-ups found on the way:
sleep_foron Drogon event-loop threads. It now uses coroutine handlers and Drogon's asyncHttpClient, so libcurl is gone (lock cleaned).httpx.AsyncClientin the lifespan.>= 8.4.2floor.Docs:
deck_fitreports 0.Verification:
verify-matrix.sh 26-failure-modeson the final commit: 6/6, 22/22 each.deck_text --checkreport clean.