Struct FlowControlConfig
pub struct FlowControlConfig {
pub mode: FlowControlMode,
pub min_window_size: usize,
pub max_window_size: usize,
pub ai_step: usize,
pub md_factor: f64,
pub no_honest_deadline: Duration,
pub persist_stall_parks: u32,
pub frame_retries: u32,
}Expand description
Client-tunable flow-control parameters. Defaults are deliberately conservative (anti-grief-preserving): the window starts at the floor and only grows on proven delivery, and the opt-in robustness knobs are off. This is the clean profile.
Flow control is enabled per-session by providing this config (the transport’s
SessionClientConfig::flow_control is an Option — None leaves the session unpaced with
today’s behaviour), so there is no separate enabled flag.
Fields§
§mode: FlowControlModeHonest-clock mode. Default [FlowControlMode::Reliable].
min_window_size: usizeMinimum in-flight bytes that are always admitted, regardless of delivery feedback or SURB supply. Guarantees the duplex socket never deadlocks (acks/keep-alives can always flow) and is the hard floor a malicious peer can never push the window below — but also never above without honest delivery. Keep small (a few frames). Default 4 KiB.
max_window_size: usizeHard ceiling on the send window, seeded from the bandwidth-delay product
(drain_rate_hint × rtt). The window never opens past this even under sustained delivery.
Default 2 MiB.
ai_step: usizeAdditive-increase step (bytes added to the window per fully-delivered window) while in congestion avoidance. Default 16 KiB.
md_factor: f64Multiplicative-decrease factor applied to the window on loss or a soft backoff hint. Must be
in (0.0, 1.0). Default 0.5 (classic AIMD).
no_honest_deadline: DurationIn [FlowControlMode::Segmentation] there is no honest delivery signal, so admission may
park indefinitely behind a shrinking SURB ceiling. This deadline bounds how long the writer
parks before it re-checks the ceiling / makes keep-progress at the floor. Default 250 ms.
persist_stall_parks: u32Persist probe (opt-in robustness). Consecutive no-progress parks before the writer admits
a bounded min_window_size beyond cwnd (still SURB-capped) to break an end-of-stream tail deadlock
on a slow/throttled return path. 0 disables it — the default, i.e. the verified clean
behaviour. A robust profile (e.g. for deliberately SURB-throttled paths) sets ~8 (≈2 s at the
default keep-progress deadline). See the PacedWriter admission logic.
frame_retries: u32Frame retransmission budget under flow control (opt-in robustness). Applied to the
reliable socket’s max_outgoing_frame_retries when flow control is enabled. 2 (the
original) is the default; a robust profile raises it (~8) so a merely-delayed ack on a
temporarily-starved return path recovers the frame instead of abandoning it (an abandoned
frame leaves a gap → stream corruption).
Implementations§
§impl FlowControlConfig
impl FlowControlConfig
pub fn robust() -> FlowControlConfig
pub fn robust() -> FlowControlConfig
The robust profile: the clean defaults plus the opt-in tail-tolerance bundle (persist
probe + larger retransmission budget) for deliberately SURB-throttled / high-latency return
paths. See Self::persist_stall_parks and Self::frame_retries.
pub fn with_bdp(
self,
drain_rate_bytes_per_sec: u64,
rtt: Duration,
) -> FlowControlConfig
pub fn with_bdp( self, drain_rate_bytes_per_sec: u64, rtt: Duration, ) -> FlowControlConfig
Convenience constructor seeding max_window_size from a bandwidth-delay product.
drain_rate_bytes_per_sec is the estimated rate at which the counterparty can drain the
return path (for a SURB-capped echo: max_surbs_per_sec / surbs_per_reply_packet × bytes_per_packet). rtt is the round-trip delivery latency.
Trait Implementations§
§impl Clone for FlowControlConfig
impl Clone for FlowControlConfig
§fn clone(&self) -> FlowControlConfig
fn clone(&self) -> FlowControlConfig
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more§impl Debug for FlowControlConfig
impl Debug for FlowControlConfig
§impl Default for FlowControlConfig
impl Default for FlowControlConfig
§fn default() -> FlowControlConfig
fn default() -> FlowControlConfig
Return FlowControlConfig { mode: Default::default(), min_window_size: 4 * 1024, max_window_size: 2 * 1024 * 1024, ai_step: 16 * 1024, md_factor: 0.5, no_honest_deadline: Duration::from_millis(250), persist_stall_parks: 0, frame_retries: 2 }
§impl PartialEq for FlowControlConfig
impl PartialEq for FlowControlConfig
impl Copy for FlowControlConfig
impl StructuralPartialEq for FlowControlConfig
Auto Trait Implementations§
impl Freeze for FlowControlConfig
impl RefUnwindSafe for FlowControlConfig
impl Send for FlowControlConfig
impl Sync for FlowControlConfig
impl Unpin for FlowControlConfig
impl UnwindSafe for FlowControlConfig
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.§impl<T> Pointable for T
impl<T> Pointable for T
§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.