- Move blocking usage queries and core lifecycle operations to background workers, limit concurrency, and prevent overlapping core operations - Coalesce statistics refreshes and consolidate category aggregations, reducing unfiltered analysis queries from 11 to 4 - Cache bundled model prices, reuse management API connections, and reduce redundant checks in the usage collector - Throttle download progress and guide positioning updates, and avoid redundant renders when core status is unchanged - Bound and coalesce configuration watcher events, and reuse a single model catalog refresh worker - Stop scheduling remaining health checks when the dialog closes and limit backend health-check concurrency - Replace overlapping OAuth polling with sequential requests, retry backoff, timeouts, and stale callback protection - Add regression tests and a statistics benchmark script, and move performance verification documentation to agent_docs
37 lines
974 B
Rust
37 lines
974 B
Rust
use std::time::{Duration, Instant};
|
|
|
|
#[derive(Default)]
|
|
pub(crate) struct ProgressThrottle {
|
|
last: Option<Instant>,
|
|
}
|
|
|
|
impl ProgressThrottle {
|
|
pub(crate) fn ready(&mut self, now: Instant, finished: bool) -> bool {
|
|
if finished
|
|
|| self
|
|
.last
|
|
.is_none_or(|last| now.duration_since(last) >= Duration::from_millis(100))
|
|
{
|
|
self.last = Some(now);
|
|
true
|
|
} else {
|
|
false
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn throttles_chunks_but_keeps_first_and_final_progress() {
|
|
let mut throttle = ProgressThrottle::default();
|
|
let now = Instant::now();
|
|
assert!(throttle.ready(now, false));
|
|
assert!(!throttle.ready(now + Duration::from_millis(10), false));
|
|
assert!(throttle.ready(now + Duration::from_millis(100), false));
|
|
assert!(throttle.ready(now + Duration::from_millis(101), true));
|
|
}
|
|
}
|