pub struct RetryConfig {
pub initial: Duration,
pub max: Duration,
pub multiplier: f64,
pub jitter: f64,
pub max_attempts: u32,
}Expand description
Retry policy for batch writes. Retries rotate across healthy replicas; the sealed batch and its deduplication token are reused unchanged.
Fields§
§initial: DurationFirst backoff delay.
max: DurationBackoff cap.
multiplier: f64Backoff growth factor per attempt.
jitter: f64Fraction of the delay randomized away (0.0..=1.0).
max_attempts: u32Total write attempts before the batch is abandoned (acknowledgements
failed, watermark stalls). 0 means unbounded — retry until the drain
deadline, at which point the attempt in flight is aborted and the batch
abandoned. The at-least-once default.
An unbounded policy holds its in-flight slot
(InflightConfig::max_per_shard) for the whole outage, since a slot
frees only when its write task ends. That is intended — it is how a
down sink back-pressures the source rather than buffering — but it does
mean a shard talking to a dead sink runs at zero in-flight capacity
until either the sink recovers or the drain deadline arrives.
Implementations§
Source§impl RetryConfig
impl RetryConfig
Sourcepub fn validate(&self) -> Result<(), RetryConfigError>
pub fn validate(&self) -> Result<(), RetryConfigError>
Reject a retry policy that would misbehave at runtime. Connectors call this from their config validation and prepend their own config path to the message, so the rules stay in one place instead of being mirrored per connector.
This is about intent, not safety. Backoff is total
for any RetryConfig — it saturates at max and never returns a
zero delay — so nothing here is load-bearing for the write loop. What
it catches is a policy no operator means: a sub-1.0 multiplier
shrinks the delay instead of backing off, a zero delay is not a
backoff at all, and both are worth failing at load rather than at 3am.
The bounds are deliberately generous and do not guarantee a
sensible policy — initial: 1ns, max: 1ns passes. They rule out the
nonsensical, not the merely aggressive.
§Errors
RetryConfigError, naming the offending key.
use spate_core::sink::{RetryConfig, RetryConfigError};
assert!(RetryConfig::default().validate().is_ok());
let hot_loop = RetryConfig { multiplier: 0.5, ..RetryConfig::default() };
assert_eq!(hot_loop.validate(), Err(RetryConfigError::Multiplier(0.5)));Trait Implementations§
Source§impl Clone for RetryConfig
impl Clone for RetryConfig
Source§fn clone(&self) -> RetryConfig
fn clone(&self) -> RetryConfig
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more