pub struct BackoffPolicy {
pub initial: Duration,
pub max: Duration,
pub jitter_percent: u8,
pub reset_after: Duration,
pub jitter_mode: JitterMode,
}Expand description
Exponential backoff configuration for restart attempts.
Fields§
§initial: DurationInitial delay for the first restart attempt.
max: DurationMaximum delay allowed after exponential growth and jitter.
jitter_percent: u8Jitter percentage in the inclusive range from zero to one hundred.
reset_after: DurationStable runtime duration after which attempt counters may be reset.
jitter_mode: JitterModeJitter mode used by the calculation.
Implementations§
Source§impl BackoffPolicy
impl BackoffPolicy
Sourcepub fn new(
initial: Duration,
max: Duration,
jitter_percent: u8,
reset_after: Duration,
) -> Self
pub fn new( initial: Duration, max: Duration, jitter_percent: u8, reset_after: Duration, ) -> Self
Creates an exponential backoff policy.
§Arguments
initial: First restart delay.max: Maximum restart delay.jitter_percent: Jitter percentage capped at one hundred.reset_after: Runtime duration after which counters may reset.
§Returns
Returns a BackoffPolicy with jitter disabled.
§Examples
use std::time::Duration;
let policy = rust_supervisor::policy::backoff::BackoffPolicy::new(
Duration::from_millis(10),
Duration::from_millis(100),
0,
Duration::from_secs(1),
);
assert_eq!(policy.delay_for_attempt(1), Duration::from_millis(10));Examples found in repository?
14fn main() {
15 // Build the reusable backoff policy.
16 let backoff = BackoffPolicy::new(
17 // Set the initial delay.
18 Duration::from_millis(100),
19 // Set the maximum delay.
20 Duration::from_secs(5),
21 // Set jitter percent.
22 10,
23 // Set the reset window.
24 Duration::from_secs(60),
25 // Finish the reusable backoff policy.
26 )
27 // Enable deterministic jitter for repeatable output.
28 .with_deterministic_jitter(42);
29 // Create the stateless policy engine.
30 let engine = PolicyEngine::new();
31
32 // Iterate over policy and exit combinations.
33 for (policy, exit) in [
34 // Include a permanent policy after success.
35 (RestartPolicy::Permanent, TaskExit::Succeeded),
36 // Include a transient external dependency failure.
37 (
38 // Select transient restart behavior.
39 RestartPolicy::Transient,
40 // Build an external dependency failure exit.
41 TaskExit::Failed {
42 // Set the failure category.
43 kind: PolicyFailureKind::ExternalDependency,
44 // Finish the failure exit.
45 },
46 // Finish the policy and exit pair.
47 ),
48 // Include a transient fatal bug failure.
49 (
50 // Select transient restart behavior.
51 RestartPolicy::Transient,
52 // Build a fatal bug failure exit.
53 TaskExit::Failed {
54 // Set the failure category.
55 kind: PolicyFailureKind::FatalBug,
56 // Finish the failure exit.
57 },
58 // Finish the policy and exit pair.
59 ),
60 // Include a temporary panic failure.
61 (
62 // Select temporary restart behavior.
63 RestartPolicy::Temporary,
64 // Build a panic failure exit.
65 TaskExit::Failed {
66 // Set the failure category.
67 kind: PolicyFailureKind::Panic,
68 // Finish the failure exit.
69 },
70 // Finish the policy and exit pair.
71 ),
72 // Finish the decision matrix.
73 ] {
74 // Calculate the restart decision.
75 let decision = engine.decide(policy, exit, 3, &backoff);
76 // Print the policy decision row.
77 println!("policy={policy:?} exit={exit:?} decision={decision:?}");
78 // Finish the matrix loop.
79 }
80
81 // Build the meltdown fuse policy.
82 let policy = MeltdownPolicy::new(
83 // Set the child restart limit.
84 2,
85 // Set the child restart window.
86 Duration::from_secs(60),
87 // Set the supervisor failure limit.
88 5,
89 // Set the supervisor failure window.
90 Duration::from_secs(60),
91 // Set the stable reset window.
92 Duration::from_secs(300),
93 // Finish the meltdown policy construction.
94 );
95 // Create the mutable meltdown tracker.
96 let mut tracker = MeltdownTracker::new(policy);
97 // Capture the current monotonic instant.
98 let now = Instant::now();
99
100 // Iterate over restart offsets.
101 for offset_ms in [0, 10, 20] {
102 // Record a child restart at the offset instant.
103 let outcome = tracker.record_child_restart(now + Duration::from_millis(offset_ms));
104 // Print the fuse state after the restart.
105 println!(
106 // Provide the output template.
107 "restart_at_ms={offset_ms} child_failures={} outcome={outcome:?}",
108 // Include the current child failure count.
109 tracker.child_failure_count(),
110 // Finish printing the fuse state.
111 );
112 // Finish the fuse loop.
113 }
114 // End the policy failure matrix example.
115}Sourcepub fn with_deterministic_jitter(self, seed: u64) -> Self
pub fn with_deterministic_jitter(self, seed: u64) -> Self
Returns this policy with deterministic jitter enabled.
§Arguments
seed: Stable seed used to derive jitter.
§Returns
Returns a new BackoffPolicy that keeps the same timing bounds.
Examples found in repository?
14fn main() {
15 // Build the reusable backoff policy.
16 let backoff = BackoffPolicy::new(
17 // Set the initial delay.
18 Duration::from_millis(100),
19 // Set the maximum delay.
20 Duration::from_secs(5),
21 // Set jitter percent.
22 10,
23 // Set the reset window.
24 Duration::from_secs(60),
25 // Finish the reusable backoff policy.
26 )
27 // Enable deterministic jitter for repeatable output.
28 .with_deterministic_jitter(42);
29 // Create the stateless policy engine.
30 let engine = PolicyEngine::new();
31
32 // Iterate over policy and exit combinations.
33 for (policy, exit) in [
34 // Include a permanent policy after success.
35 (RestartPolicy::Permanent, TaskExit::Succeeded),
36 // Include a transient external dependency failure.
37 (
38 // Select transient restart behavior.
39 RestartPolicy::Transient,
40 // Build an external dependency failure exit.
41 TaskExit::Failed {
42 // Set the failure category.
43 kind: PolicyFailureKind::ExternalDependency,
44 // Finish the failure exit.
45 },
46 // Finish the policy and exit pair.
47 ),
48 // Include a transient fatal bug failure.
49 (
50 // Select transient restart behavior.
51 RestartPolicy::Transient,
52 // Build a fatal bug failure exit.
53 TaskExit::Failed {
54 // Set the failure category.
55 kind: PolicyFailureKind::FatalBug,
56 // Finish the failure exit.
57 },
58 // Finish the policy and exit pair.
59 ),
60 // Include a temporary panic failure.
61 (
62 // Select temporary restart behavior.
63 RestartPolicy::Temporary,
64 // Build a panic failure exit.
65 TaskExit::Failed {
66 // Set the failure category.
67 kind: PolicyFailureKind::Panic,
68 // Finish the failure exit.
69 },
70 // Finish the policy and exit pair.
71 ),
72 // Finish the decision matrix.
73 ] {
74 // Calculate the restart decision.
75 let decision = engine.decide(policy, exit, 3, &backoff);
76 // Print the policy decision row.
77 println!("policy={policy:?} exit={exit:?} decision={decision:?}");
78 // Finish the matrix loop.
79 }
80
81 // Build the meltdown fuse policy.
82 let policy = MeltdownPolicy::new(
83 // Set the child restart limit.
84 2,
85 // Set the child restart window.
86 Duration::from_secs(60),
87 // Set the supervisor failure limit.
88 5,
89 // Set the supervisor failure window.
90 Duration::from_secs(60),
91 // Set the stable reset window.
92 Duration::from_secs(300),
93 // Finish the meltdown policy construction.
94 );
95 // Create the mutable meltdown tracker.
96 let mut tracker = MeltdownTracker::new(policy);
97 // Capture the current monotonic instant.
98 let now = Instant::now();
99
100 // Iterate over restart offsets.
101 for offset_ms in [0, 10, 20] {
102 // Record a child restart at the offset instant.
103 let outcome = tracker.record_child_restart(now + Duration::from_millis(offset_ms));
104 // Print the fuse state after the restart.
105 println!(
106 // Provide the output template.
107 "restart_at_ms={offset_ms} child_failures={} outcome={outcome:?}",
108 // Include the current child failure count.
109 tracker.child_failure_count(),
110 // Finish printing the fuse state.
111 );
112 // Finish the fuse loop.
113 }
114 // End the policy failure matrix example.
115}Sourcepub fn delay_for_attempt(&self, attempt: u64) -> Duration
pub fn delay_for_attempt(&self, attempt: u64) -> Duration
Calculates a restart delay for a one-based attempt number.
§Arguments
attempt: One-based restart attempt. Zero is treated as one.
§Returns
Returns a delay capped by BackoffPolicy::max.
Sourcepub fn should_reset(&self, stable_for: Duration) -> bool
pub fn should_reset(&self, stable_for: Duration) -> bool
Reports whether a stable runtime duration should reset counters.
§Arguments
stable_for: Duration for which the child has run without failure.
§Returns
Returns true when stable_for reaches BackoffPolicy::reset_after.
Trait Implementations§
Source§impl Clone for BackoffPolicy
impl Clone for BackoffPolicy
Source§fn clone(&self) -> BackoffPolicy
fn clone(&self) -> BackoffPolicy
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for BackoffPolicy
impl Debug for BackoffPolicy
Source§impl<'de> Deserialize<'de> for BackoffPolicy
impl<'de> Deserialize<'de> for BackoffPolicy
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl PartialEq for BackoffPolicy
impl PartialEq for BackoffPolicy
Source§fn eq(&self, other: &BackoffPolicy) -> bool
fn eq(&self, other: &BackoffPolicy) -> bool
self and other values to be equal, and is used by ==.Source§impl Serialize for BackoffPolicy
impl Serialize for BackoffPolicy
impl Copy for BackoffPolicy
impl Eq for BackoffPolicy
impl StructuralPartialEq for BackoffPolicy
Auto Trait Implementations§
impl Freeze for BackoffPolicy
impl RefUnwindSafe for BackoffPolicy
impl Send for BackoffPolicy
impl Sync for BackoffPolicy
impl Unpin for BackoffPolicy
impl UnsafeUnpin for BackoffPolicy
impl UnwindSafe for BackoffPolicy
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,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
Source§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();Source§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
Source§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
Source§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
Source§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
Source§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
Source§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
Source§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
Source§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
Source§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();Source§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
Source§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
Source§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
Source§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
Source§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
Source§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
Source§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
Source§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
Source§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
Source§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
Source§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling Attribute value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();Source§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
Source§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi Quirk value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();Source§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
Source§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the Condition value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);