51 lines
1.3 KiB
Rust
51 lines
1.3 KiB
Rust
//! Sync buffer for `session_metrics::Metric` values queued from inside
|
|
//! Worker callbacks (which run synchronously and cannot themselves
|
|
//! perform `async` store writes).
|
|
//!
|
|
//! Pod drains this buffer in `persist_turn` and writes each metric via
|
|
//! `session_metrics::record_metric`, alongside the regular `LlmUsage`
|
|
//! entries.
|
|
|
|
use std::sync::Mutex;
|
|
|
|
use session_metrics::Metric;
|
|
|
|
pub(crate) struct MetricsTracker {
|
|
pending: Mutex<Vec<Metric>>,
|
|
}
|
|
|
|
impl MetricsTracker {
|
|
pub(crate) fn new() -> Self {
|
|
Self {
|
|
pending: Mutex::new(Vec::new()),
|
|
}
|
|
}
|
|
|
|
/// Queue a metric for the next `persist_turn` flush.
|
|
pub(crate) fn push(&self, metric: Metric) {
|
|
self.pending.lock().unwrap().push(metric);
|
|
}
|
|
|
|
/// Drain all queued metrics. Called by Pod after a run completes.
|
|
pub(crate) fn drain(&self) -> Vec<Metric> {
|
|
std::mem::take(&mut *self.pending.lock().unwrap())
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn push_then_drain_returns_in_order_and_clears() {
|
|
let t = MetricsTracker::new();
|
|
t.push(Metric::now("a"));
|
|
t.push(Metric::now("b"));
|
|
let drained = t.drain();
|
|
assert_eq!(drained.len(), 2);
|
|
assert_eq!(drained[0].name, "a");
|
|
assert_eq!(drained[1].name, "b");
|
|
assert!(t.drain().is_empty());
|
|
}
|
|
}
|