policy_failure_matrix/policy_failure_matrix.rs
1//! Demonstrates policy decisions across typed task exits and fuse tracking.
2
3// Import restart backoff policy values.
4use rust_supervisor::policy::backoff::BackoffPolicy;
5// Import typed restart policy decision values.
6use rust_supervisor::policy::decision::{PolicyEngine, PolicyFailureKind, RestartPolicy, TaskExit};
7// Import meltdown fuse policy values.
8use rust_supervisor::policy::meltdown::{MeltdownPolicy, MeltdownTracker};
9// Import duration and instant values for deterministic examples.
10use std::time::{Duration, Instant};
11
12// Run the policy failure matrix example.
13/// Runs the policy failure matrix example.
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}