1use do_over::{error::DoOverError, policy::Policy, timeout::TimeoutPolicy};
7use std::time::{Duration, Instant};
8
9#[tokio::main]
10async fn main() {
11 println!("=== Do-Over Timeout Policy Example ===\n");
12
13 fast_operation_example().await;
15
16 println!("\n{}\n", "─".repeat(60));
17
18 slow_operation_example().await;
20
21 println!("\n{}\n", "─".repeat(60));
22
23 edge_case_example().await;
25}
26
27async fn fast_operation_example() {
28 println!("📌 Scenario 1: Fast Operation (completes within timeout)");
29 println!(" Configuration: timeout=500ms, operation_time=100ms\n");
30
31 let policy = TimeoutPolicy::new(Duration::from_millis(500));
32 let start = Instant::now();
33
34 let result: Result<String, DoOverError<String>> = policy
35 .execute(|| async {
36 println!(" → Operation started...");
37 tokio::time::sleep(Duration::from_millis(100)).await;
38 println!(" → Operation completed!");
39 Ok("Fast operation result".to_string())
40 })
41 .await;
42
43 let elapsed = start.elapsed();
44 println!("\n Result: {:?}", result.unwrap());
45 println!(" Elapsed: {:?} (well under 500ms timeout)", elapsed);
46}
47
48async fn slow_operation_example() {
49 println!("📌 Scenario 2: Slow Operation (exceeds timeout)");
50 println!(" Configuration: timeout=200ms, operation_time=500ms\n");
51
52 let policy = TimeoutPolicy::new(Duration::from_millis(200));
53 let start = Instant::now();
54
55 let result: Result<String, DoOverError<String>> = policy
56 .execute(|| async {
57 println!(" → Operation started (will take 500ms)...");
58 tokio::time::sleep(Duration::from_millis(500)).await;
59 println!(" → This should not print!");
61 Ok("Slow operation result".to_string())
62 })
63 .await;
64
65 let elapsed = start.elapsed();
66
67 match result {
68 Err(DoOverError::Timeout) => {
69 println!(" → Operation cancelled due to timeout!");
70 println!("\n Result: DoOverError::Timeout");
71 }
72 _ => println!(" Unexpected result: {:?}", result),
73 }
74
75 println!(" Elapsed: {:?} (stopped at ~200ms timeout)", elapsed);
76 println!("\n 💡 The operation was cancelled - no resources wasted!");
77}
78
79async fn edge_case_example() {
80 println!("📌 Scenario 3: Edge Case (operation completes just in time)");
81 println!(" Configuration: timeout=300ms, operation_time=250ms\n");
82
83 let policy = TimeoutPolicy::new(Duration::from_millis(300));
84 let start = Instant::now();
85
86 let result: Result<String, DoOverError<String>> = policy
87 .execute(|| async {
88 println!(" → Operation started (will take 250ms)...");
89 tokio::time::sleep(Duration::from_millis(250)).await;
90 println!(" → Operation completed just in time!");
91 Ok("Completed with 50ms to spare".to_string())
92 })
93 .await;
94
95 let elapsed = start.elapsed();
96
97 match result {
98 Ok(msg) => {
99 println!("\n Result: ✅ {}", msg);
100 }
101 Err(DoOverError::Timeout) => {
102 println!("\n Result: ❌ Timeout (race condition)");
103 }
104 Err(e) => {
105 println!("\n Result: {:?}", e);
106 }
107 }
108
109 println!(" Elapsed: {:?}", elapsed);
110}