pub struct BoundedStream { /* private fields */ }Expand description
A bounded stream backed by a ring buffer.
When writes exceed capacity, the oldest data is evicted to make room. This prevents unbounded memory growth from chatty commands while still keeping recent output available for inspection.
§Example
use kaish_kernel::scheduler::BoundedStream;
let stream = BoundedStream::new(100); // 100 byte max
stream.write(b"hello ").await;
stream.write(b"world").await;
let snapshot = stream.read().await;
assert_eq!(&snapshot, b"hello world");Implementations§
Source§impl BoundedStream
impl BoundedStream
Sourcepub fn new(max_size: usize) -> Self
pub fn new(max_size: usize) -> Self
Create a new bounded stream with the specified maximum size.
Sourcepub fn default_size() -> Self
pub fn default_size() -> Self
Create a new bounded stream with the default max size (10MB).
Sourcepub async fn write(&self, data: &[u8])
pub async fn write(&self, data: &[u8])
Write data to the stream.
If the write would exceed capacity, the oldest data is evicted first. Writing to a closed stream is silently ignored.
Sourcepub async fn read(&self) -> Vec<u8> ⓘ
pub async fn read(&self) -> Vec<u8> ⓘ
Read a snapshot of the current buffer contents.
Returns a copy of all data currently in the buffer. The buffer is not modified.
Sourcepub async fn read_string(&self) -> String
pub async fn read_string(&self) -> String
Read the current buffer as a string (lossy UTF-8 conversion).
Sourcepub async fn close(&self)
pub async fn close(&self)
Close the stream, indicating no more writes are expected.
Subsequent writes will be silently ignored.
Sourcepub async fn has_overflowed(&self) -> bool
pub async fn has_overflowed(&self) -> bool
Whether this stream has ever evicted data due to overflow.
write silently drops the oldest bytes once the ring fills — this is
the hot-path check capture sites use to detect that loss so they can
surface it instead of reporting clean success (GH #191). Equivalent to
stats().await.bytes_evicted > 0, but avoids building the full
StreamStats when the caller only needs the boolean.
Sourcepub async fn changed_since(&self, seen_total_written: u64) -> StreamStats
pub async fn changed_since(&self, seen_total_written: u64) -> StreamStats
Wait until this stream has written more than seen_total_written
lifetime bytes, or has closed. Returns the stats that ended the wait,
so the caller’s next call passes back stats.total_written.
This is the alternative to a poll loop for an embedder tailing a
running job’s output. Pass 0 on the first call to wake on the first
byte. A closed stream returns immediately, every time — the caller
checks stats.closed and stops, rather than looping on a stream that
can never change again.
The registration happens before the read, not after: Notify only
reaches waiters that are already registered, so reading first would
drop a write that landed in between and park until the next one.
Sourcepub async fn stats(&self) -> StreamStats
pub async fn stats(&self) -> StreamStats
Get stream statistics.
Trait Implementations§
Source§impl Clone for BoundedStream
impl Clone for BoundedStream
Source§fn clone(&self) -> BoundedStream
fn clone(&self) -> BoundedStream
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl !RefUnwindSafe for BoundedStream
impl !UnwindSafe for BoundedStream
impl Freeze for BoundedStream
impl Send for BoundedStream
impl Sync for BoundedStream
impl Unpin for BoundedStream
impl UnsafeUnpin for BoundedStream
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
Source§fn with_current_context(self) -> WithContext<Self> ⓘ
fn with_current_context(self) -> WithContext<Self> ⓘ
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
impl<T> OrderedSeq<'_, T> for Twhere
T: Clone,
Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<'p, T> Seq<'p, T> for Twhere
T: Clone,
impl<'p, T> Seq<'p, T> for Twhere
T: Clone,
Source§impl<T, S> SpanWrap<S> for Twhere
S: WrappingSpan<T>,
impl<T, S> SpanWrap<S> for Twhere
S: WrappingSpan<T>,
Source§fn with_span(self, span: S) -> <S as WrappingSpan<Self>>::Spanned
fn with_span(self, span: S) -> <S as WrappingSpan<Self>>::Spanned
WrappingSpan::make_wrapped to wrap an AST node in a span.