Skip to main content

agentkit_reporting/
buffered.rs

1//! Batch-buffered reporter adapter.
2//!
3//! [`BufferedReporter`] enqueues events and forwards them to an inner
4//! [`LoopObserver`] in batches — either when the buffer reaches a configured
5//! capacity or on an explicit [`flush`](BufferedReporter::flush) call.
6//! Remaining events are flushed automatically on drop.
7
8use agentkit_loop::{AgentEvent, LoopObserver};
9
10/// Reporter adapter that enqueues events for batch flushing.
11///
12/// Wraps any [`LoopObserver`] and delivers events in batches rather than
13/// one-at-a-time. This is useful when the inner reporter benefits from
14/// amortised work (e.g. a network sink that batches writes).
15///
16/// # Example
17///
18/// ```rust
19/// use agentkit_reporting::{BufferedReporter, UsageReporter};
20///
21/// // Buffer up to 64 events before forwarding to the inner reporter.
22/// let reporter = BufferedReporter::new(UsageReporter::new(), 64);
23/// ```
24pub struct BufferedReporter<T: LoopObserver> {
25    inner: T,
26    buffer: Vec<AgentEvent>,
27    capacity: usize,
28}
29
30impl<T: LoopObserver> BufferedReporter<T> {
31    /// Creates a new `BufferedReporter` that buffers up to `capacity` events
32    /// before flushing them to `inner`.
33    ///
34    /// A capacity of `0` disables automatic flushing — events are only
35    /// delivered when [`flush`](BufferedReporter::flush) is called explicitly
36    /// (or on drop).
37    pub fn new(inner: T, capacity: usize) -> Self {
38        Self {
39            inner,
40            buffer: Vec::with_capacity(capacity),
41            capacity,
42        }
43    }
44
45    /// Delivers all buffered events to the inner observer and clears the
46    /// buffer.
47    pub fn flush(&mut self) {
48        for event in self.buffer.drain(..) {
49            self.inner.handle_event(event);
50        }
51    }
52
53    /// Returns the number of events currently buffered.
54    pub fn pending(&self) -> usize {
55        self.buffer.len()
56    }
57
58    /// Returns a reference to the inner observer.
59    pub fn inner(&self) -> &T {
60        &self.inner
61    }
62
63    /// Returns a mutable reference to the inner observer.
64    pub fn inner_mut(&mut self) -> &mut T {
65        &mut self.inner
66    }
67}
68
69impl<T: LoopObserver> LoopObserver for BufferedReporter<T> {
70    fn handle_event(&mut self, event: AgentEvent) {
71        self.buffer.push(event);
72        if self.capacity > 0 && self.buffer.len() >= self.capacity {
73            self.flush();
74        }
75    }
76}
77
78impl<T: LoopObserver> Drop for BufferedReporter<T> {
79    fn drop(&mut self) {
80        self.flush();
81    }
82}