pub struct TranscriptBatchPolicy {
pub max_batch_events: NonZeroUsize,
pub max_hold: Duration,
}Expand description
The transcript drain’s flush policy: how many queued events one durable commit may carry, and how long the drain may wait to fill that batch.
§There is no default, deliberately
Both values are a deployment trade between store cost and transcript
latency, so neither is invented here: crate::config::ObservabilityConfig
carries them as Options with no default and the boot path refuses to build
a publisher without them (the websocket.cluster_broadcast_capacity
pattern). A server whose operator has not ruled on them does not start, and
says which keys are missing.
§Durability contract
Unchanged for the caller of ActivityEventPublisher::publish /
ActivityEventPublisher::publish_all: those return only after the
events are durably committed, and an event that has been acked as persisted
(a returned store_seq) is exactly as durable as before.
What max_hold extends is the window in which an event sits in the
server’s IN-MEMORY transcript queue before the drain commits it. That window
already existed and is already lossy: the observability tap hands events to a
bounded in-process channel, and everything queued there is lost if the server
process dies. max_hold lengthens that pre-existing window by at most its own
value, and max_batch_events bounds how many events can be waiting in it
beyond what the channel already held. Nothing that was durable becomes
non-durable; a strictly bounded amount of not-yet-durable transcript stays
not-yet-durable for strictly bounded longer.
That trade is acceptable HERE and would not be elsewhere, because the O
keyspace is observability, never replay authority: workflow correctness lives
on the E-stream, whose append path is untouched by this policy. Losing the
last few hundred milliseconds of an agent’s transcript to a kill-9 costs
transcript, never a workflow decision — which is the same reason the drain
already logs and drops an event the store refuses instead of failing the
activity. An operator who wants the old timing sets max_hold_ms = 0: the
drain then commits whatever is already queued the moment it can, coalescing
only what genuinely arrived together, with no added window at all.
Fields§
§max_batch_events: NonZeroUsizeMaximum events in one durable commit (observability.max_batch_events).
max_hold: DurationMaximum time the drain waits for a partial batch to fill
(observability.max_batch_hold_ms). Zero means “never wait”.
Implementations§
Source§impl TranscriptBatchPolicy
impl TranscriptBatchPolicy
Sourcepub const UNBATCHED: Self
pub const UNBATCHED: Self
The IDENTITY policy: one event per durable commit, never held.
This is the pre-batching behaviour, and the only policy that assumes nothing about a deployment — which is exactly why it is the fallback for the embedder/test state constructors that bypass config validation and cannot refuse to build, and the policy under which the single-event sequencing tests run. A config-driven server never reaches it: it states its own policy or it does not start.
Trait Implementations§
Source§impl Clone for TranscriptBatchPolicy
impl Clone for TranscriptBatchPolicy
Source§fn clone(&self) -> TranscriptBatchPolicy
fn clone(&self) -> TranscriptBatchPolicy
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl Copy for TranscriptBatchPolicy
Source§impl Debug for TranscriptBatchPolicy
impl Debug for TranscriptBatchPolicy
impl Eq for TranscriptBatchPolicy
Source§impl PartialEq for TranscriptBatchPolicy
impl PartialEq for TranscriptBatchPolicy
impl StructuralPartialEq for TranscriptBatchPolicy
Auto Trait Implementations§
impl Freeze for TranscriptBatchPolicy
impl RefUnwindSafe for TranscriptBatchPolicy
impl Send for TranscriptBatchPolicy
impl Sync for TranscriptBatchPolicy
impl Unpin for TranscriptBatchPolicy
impl UnsafeUnpin for TranscriptBatchPolicy
impl UnwindSafe for TranscriptBatchPolicy
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
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> ⓘ
Source§impl<T> IntoMaybeUndefined<T> for T
impl<T> IntoMaybeUndefined<T> for T
Source§fn into_maybe_undefined(self) -> MaybeUndefined<T>
fn into_maybe_undefined(self) -> MaybeUndefined<T>
Source§impl<T> IntoOption<T> for T
impl<T> IntoOption<T> for T
Source§fn into_option(self) -> Option<T>
fn into_option(self) -> Option<T>
Source§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request