GeezerVison is showing github.com — fda: retry transient request failures by gz · Pull Request #6890 · feldera/feldera
Conversation
gz
commented
Aug 19, 2026
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
Every request the fda client sends now retries transient failures with exponential backoff, controlled by the global --retries flag (FELDERA_RETRIES, default 3, 0 disables). This addresses the fda half of feldera/cloud#1907, where a single connect timeout to a freshly rescheduled pipeline pod failed fda clock-advance and with it the integration suite.
Three commits:
- Remove the bench result-upload path.
fda bench still runs benchmarks and prints results; the upload to benchmarks.feldera.io was unused. Deletes the generated Bencher client, bench_openapi.json, fda's build.rs, and the --upload/BENCHER_* flags.
- Retry transient request failures. The retry layer lives in
feldera-rest-api as a ClientHooks::exec override (progenitor 0.7 → 0.11.2, the newest release on reqwest 0.12), so all fda call sites get it without changes. Idempotent operations (GET/HEAD/PUT/DELETE plus desired-state POSTs) retry on any transport failure and on HTTP 408/429/502/503/504. Non-idempotent operations (ingest, clock-advance, transactions) retry only when the first attempt provably never reached its target: a local connect failure, or a 503 PipelineInteractionUnreachable whose body carries the api-server's connect-phase wording. A Retry-After header overrides the computed backoff. This mirrors the Python SDK's RetryConfig, but gates statuses and timeouts on idempotency, which the Python SDK does not.
- Pick the 502 retry wait by probing cluster health. Ports the Python SDK's cluster-aware 502 handling: before retrying a 502 the client probes
/v0/cluster_healthz (200 only when every service is healthy). Healthy means the 502 was spurious and the retry runs immediately; unhealthy (e.g. an upgrade in progress) waits a flat unhealthy_backoff (90s per retry, so 270s total at the default 3 retries) instead of ramping exponentially.
Describe Manual Test Plan
- Ran
crates/fda/test.bash end to end against the enterprise dev instance including the pclock clock-advance section that flakes in CI.
- Live retry smoke test:
FELDERA_RETRIES=1 fda pipelines against an unreachable host logs the retry and then surfaces the error.
- Each retry behavior test was validated to fail with the behavior it guards reverted (hook impl removed, transport-retry condition narrowed,
Retry-After ignored, health probe removed).
Checklist
- Unit tests added/updated
- Integration tests added/updated
- Documentation updated
- Changelog updated
Breaking Changes?
Mark if you think the answer is yes for any of these components:
Describe Incompatible Changes
fda bench loses the --upload, --project, --branch, --start-point*, --benchmark-host, and --benchmark-token flags (BENCHER_* env vars).
feldera-rest-api crate API: Client::new/Client::new_with_client take a new RetryPolicy argument, and the progenitor 0.11 Error enum replaces PreHookError/PostHookError with Custom. Retrying changes client behavior for consumers that relied on single-attempt semantics; construct the client with RetryPolicy::none() to opt out.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
fda bench still runs benchmarks and prints results in Bencher Metric
Format; the upload to benchmarks.feldera.io is no longer used. Delete the
generated Bencher client, bench_openapi.json, fda's build.rs (which only
generated that client), and the --upload/BENCHER_* flags.
Signed-off-by: Gerd Zellweger <[email protected]>
A single connect timeout to a freshly rescheduled pipeline pod fails the
whole command today; three CI runs died this way (feldera/cloud#1907).
Every request the fda client sends now retries transient failures with
exponential backoff (2s, doubling, capped at 60s), controlled by the
global --retries flag (FELDERA_RETRIES, default 3, 0 disables).
Idempotent operations (GET/HEAD/PUT/DELETE plus desired-state POSTs)
retry on any transport failure and on HTTP 408/429/502/503/504. Requests
that are unsafe to repeat (ingest, clock-advance, transactions) retry
only when the first attempt provably never reached its target: a local
connect failure, or a 503 PipelineInteractionUnreachable whose body
carries the api-server's connect-phase wording. A Retry-After header
overrides the computed backoff. This mirrors the Python SDK's
RetryConfig, but gates statuses and timeouts on idempotency, which the
Python SDK does not.
The retry layer lives in feldera-rest-api as a ClientHooks::exec
override, so it needs no per-call-site changes in fda. That hook
requires progenitor 0.11.2 (0.14 is current but requires reqwest 0.13;
0.11.2 is the newest release on reqwest 0.12). The bump also forced a
StartFromCheckpoint type replacement (new typify generates a
self-referential newtype for that schema) and replaced the removed
Error::{PreHookError,PostHookError} variants with Error::Custom.
Signed-off-by: Gerd Zellweger <[email protected]>
A 502 originates in front of the api-server and is ambiguous: a load
balancer hiccup wants an immediate retry, a cluster upgrade wants a long
flat wait. Before retrying a 502 the client now probes
/v0/cluster_healthz (which answers 200 only when every service is
healthy): healthy means the 502 was spurious and the retry runs
immediately; unhealthy waits the new RetryPolicy::unhealthy_backoff
(90s flat per retry, uncapped by max_backoff; 270s total at the default
3 retries) instead of ramping exponentially. Ports the Python SDK's
cluster-aware 502 handling, deciding on the probe's status code rather
than parsing its body.
The wait selection moved into next_wait(), a pure function with
deterministic unit tests; the integration tests assert request counts
only, no elapsed-time assertions.
Signed-off-by: Gerd Zellweger <[email protected]>
Uh oh!
There was an error while loading. Please reload this page.
Reviewers
blp
blp approved these changes
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
Uh oh!
There was an error while loading. Please reload this page.
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.
|