entrenar/train/tui/
refresh.rs1use std::time::{Duration, Instant};
6
7#[derive(Debug, Clone)]
9pub struct RefreshPolicy {
10 pub min_interval: Duration,
12 pub max_interval: Duration,
14 pub step_interval: usize,
16 last_refresh: Instant,
18 last_step: usize,
20}
21
22impl Default for RefreshPolicy {
23 fn default() -> Self {
24 Self {
25 min_interval: Duration::from_millis(50),
26 max_interval: Duration::from_millis(1000),
27 step_interval: 10,
28 last_refresh: Instant::now(),
29 last_step: 0,
30 }
31 }
32}
33
34impl RefreshPolicy {
35 pub fn new(min_ms: u64, max_ms: u64, step_interval: usize) -> Self {
37 Self {
38 min_interval: Duration::from_millis(min_ms),
39 max_interval: Duration::from_millis(max_ms),
40 step_interval,
41 last_refresh: Instant::now(),
42 last_step: 0,
43 }
44 }
45
46 pub fn should_refresh(&mut self, global_step: usize) -> bool {
48 let elapsed = self.last_refresh.elapsed();
49
50 if elapsed >= self.max_interval {
52 self.last_refresh = Instant::now();
53 self.last_step = global_step;
54 return true;
55 }
56
57 if elapsed < self.min_interval {
59 return false;
60 }
61
62 if global_step.saturating_sub(self.last_step) >= self.step_interval {
64 self.last_refresh = Instant::now();
65 self.last_step = global_step;
66 return true;
67 }
68
69 false
70 }
71
72 pub fn force_refresh(&mut self, global_step: usize) {
74 self.last_refresh = Instant::now();
75 self.last_step = global_step;
76 }
77
78 #[cfg(test)]
80 fn advance_time(&mut self, duration: Duration) {
81 self.last_refresh -= duration;
82 }
83}
84
85#[cfg(test)]
86mod tests {
87 use super::*;
88
89 #[test]
90 fn test_refresh_policy_default() {
91 let policy = RefreshPolicy::default();
92 assert_eq!(policy.min_interval, Duration::from_millis(50));
93 assert_eq!(policy.max_interval, Duration::from_millis(1000));
94 assert_eq!(policy.step_interval, 10);
95 }
96
97 #[test]
98 fn test_refresh_policy_new() {
99 let policy = RefreshPolicy::new(100, 500, 5);
100 assert_eq!(policy.min_interval, Duration::from_millis(100));
101 assert_eq!(policy.max_interval, Duration::from_millis(500));
102 assert_eq!(policy.step_interval, 5);
103 }
104
105 #[test]
106 fn test_refresh_policy_rate_limiting() {
107 let mut policy = RefreshPolicy::new(10_000, 60_000, 1);
110 policy.force_refresh(0);
111
112 let blocked = !policy.should_refresh(1);
114 assert!(blocked, "Immediate refresh should be blocked");
115
116 policy.advance_time(Duration::from_millis(15_000));
118 let allowed = policy.should_refresh(2);
119 assert!(allowed, "Refresh should be allowed after min_interval");
120 }
121
122 #[test]
123 fn test_refresh_policy_step_interval() {
124 let mut policy = RefreshPolicy::new(0, 10000, 10);
125 policy.force_refresh(0);
126
127 policy.advance_time(Duration::from_millis(20));
129
130 assert!(!policy.should_refresh(5));
132 assert!(policy.should_refresh(10));
134 }
135
136 #[test]
137 fn test_refresh_policy_force_refresh() {
138 let mut policy = RefreshPolicy::default();
139 policy.force_refresh(100);
140 assert_eq!(policy.last_step, 100);
141 }
142
143 #[test]
144 fn test_refresh_policy_max_interval_triggers() {
145 let mut policy = RefreshPolicy::new(10, 50, 1000);
146 policy.force_refresh(0);
147
148 policy.advance_time(Duration::from_millis(500));
150
151 assert!(policy.should_refresh(1));
153 }
154
155 #[test]
156 fn test_refresh_policy_clone() {
157 let policy = RefreshPolicy::new(100, 500, 5);
158 let cloned = policy.clone();
159 assert_eq!(policy.min_interval, cloned.min_interval);
160 assert_eq!(policy.max_interval, cloned.max_interval);
161 assert_eq!(policy.step_interval, cloned.step_interval);
162 }
163
164 #[test]
165 fn test_refresh_policy_debug() {
166 let policy = RefreshPolicy::default();
167 let debug_str = format!("{policy:?}");
168 assert!(debug_str.contains("RefreshPolicy"));
169 }
170
171 #[test]
172 fn test_refresh_policy_no_refresh_below_step_interval() {
173 let mut policy = RefreshPolicy::new(0, 10000, 100);
174 policy.force_refresh(0);
175
176 policy.advance_time(Duration::from_millis(20));
178
179 assert!(!policy.should_refresh(50));
181 assert!(!policy.should_refresh(99));
182 assert!(policy.should_refresh(100));
184 }
185}