Skip to content

refactor: consolidate exp backoff config into pluto_core::expbackoff#505

Open
varex83agent wants to merge 1 commit into
mainfrom
bohdan/expbackoff-consolidation
Open

refactor: consolidate exp backoff config into pluto_core::expbackoff#505
varex83agent wants to merge 1 commit into
mainfrom
bohdan/expbackoff-consolidation

Conversation

@varex83agent

Copy link
Copy Markdown
Collaborator

Summary

Charon has a single app/expbackoff package (FastConfig: 100ms/5s, DefaultConfig: 1s/120s, both ×1.6 with 0.2 jitter). In Pluto the equivalent backon::ExponentialBuilder setup was copy-pasted across core/scheduler.rs, app/sse/mod.rs, and p2p/bootnode.rs.

This PR extracts a shared pluto_core::expbackoff module exposing fast() and default() builders and migrates the three call sites, closing the TODOs at scheduler.rs:722 and sse/mod.rs:506.

Latent bug fixed

While consolidating, bootnode.rs::query_relay_addresses was found to omit .without_max_times() on its backon .retry() call, so it silently capped at backon's default of 3 retries. Go's queryRelayAddrs is documented "It retries until the context is cancelled" (and its caller uses WithFastConfig() in a for ctx.Err() == nil loop). Routing it through expbackoff::fast() (which includes without_max_times) restores the Go-equivalent behavior — it now retries until the cancel token fires.

Note: the consolidation prompt attributed this to relay/dial.rs, but that file is a hand-rolled Stream (not a backon builder) that already retries forever and reproduces Go's exact ±20% jitter math — so it is intentionally left untouched. cli/relay.rs and app/retry.rs use deliberately distinct configs and are out of scope.

Notes

  • backon::with_jitter() is an approximation of Go's ±20% multiplicative jitter, documented in the new module. Every migrated site already used .with_jitter(), so there is no behavioral change beyond the bootnode retry-cap fix.
  • sse::reconnect_backoff() is kept local — it's DEFAULT_RETRY-based, not a Go Fast/Default config.

Verification

  • cargo +nightly fmt --all --check
  • cargo clippy -p pluto-core -p pluto-app -p pluto-p2p --all-targets --all-features -- -D warnings
  • cargo test -p pluto-core -p pluto-app -p pluto-p2p --all-features ✅ (57 / 542 / 96 passed, 0 failed)

🤖 Generated with Claude Code

Charon defines a single app/expbackoff package (FastConfig: 100ms/5s,
DefaultConfig: 1s/120s, x1.6, 0.2 jitter). The equivalent backon
ExponentialBuilder setup was copy-pasted across scheduler.rs, sse/mod.rs
and bootnode.rs. Extract a shared pluto_core::expbackoff module exposing
fast() and default() builders and migrate the three call sites, closing
the TODOs at scheduler.rs:722 and sse/mod.rs:506.

While consolidating, fix a latent divergence in bootnode.rs: its
query_relay_addresses builder omitted without_max_times(), so it silently
capped at backon's default of 3 retries. Go's queryRelayAddrs is
documented "It retries until the context is cancelled"; routing it
through expbackoff::fast() restores that behavior.

dial.rs is left untouched: it is a hand-rolled Stream (not a backon
builder) that already retries forever and reproduces Go's exact jitter
math. cli/relay.rs and app/retry.rs use deliberately distinct configs
and are out of scope.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@varex83 varex83 requested review from emlautarom1 and iamquang95 and removed request for emlautarom1 June 30, 2026 16:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant