Skip to main content

SchemaStore

Struct SchemaStore 

Source
pub struct SchemaStore { /* private fields */ }
Available on crate feature decode only.
Expand description

Per-producer schema sets, fetched lazily and cached for the process.

Bounded (#340). All three maps are keyed by a producer name lifted out of arbitrary bus traffic, so all three are BoundedLru at DEFAULT_MAX_PRODUCERS, and each keeps its own eviction count — SchemaStore::bounds, beside SchemaStore::known.

Implementations§

Source§

impl SchemaStore

Source

pub fn new(base: impl Into<String>, timeout: Duration) -> Self

Source

pub fn bounded( base: impl Into<String>, timeout: Duration, max_producers: usize, ) -> Self

A store that remembers at most max_producers producers (#340).

Source

pub fn bounds(&self) -> StoreBounds

What the bounds hold and what they have cost (#340, RFC 13 §3 O6).

Read it beside known: that says what the store can answer for, this says what it stopped being able to answer for.

Source

pub fn seal(&self) -> Sealed<'_>

Stop decodes from going to the bus until the guard drops (#337).

A judging window’s drain loop calls decode_sample per sample, and on a cache miss that used to be a describe GET, awaited inside the loop, bounded by this store’s timeout. Nobody drains the monitor’s bounded broadcast while it is in flight, so the window loses samples to its own decode — and loses them twice over, because the window’s deadline does not extend to cover the wait. Self-inflicted Dropped(n) in the one place where the whole product is a verdict about a window (RFC 13 §3 O6).

Sealed, a miss is simply a miss: set_for answers from the cache or returns None, which reads through as NotValidated(NoSchema) — “asked, none served” — and records nothing, because a seal is a fact about the observer, not about the producer.

It does not stop the store talking to the fleet: prewarm still asks. That is the distinction — a deliberate ask, made where the caller has decided it is safe to wait, is fine; an incidental one from inside a drain loop is not.

Source

pub fn register_decoder(&self, decoder: Box<dyn PayloadDecoder>)

Register a custom kind’s codec (RFC 08 §7 is open to kinds beyond the built-ins; later registrations win on conflict).

Takes &self, unlike the decoders_mut it replaces: every frontend shares one store through an Arc, so a &mut self setter could only be called before the store was shared — which is to say, not by the code that has the store.

Source

pub fn insert(&self, producer: impl Into<String>, set: SchemaSet)

Pre-warm one producer’s served set with a describe reply the caller already holds (RFC 08 §7).

The doctor fetches every producer’s describe document in its GET phase and then opens a listen window; without this the window’s store starts empty and re-asks the fleet, mid-window, for documents the same run already has — load this tool put on the fleet for nothing.

Authoritative, not a hint: it overwrites whatever the store held, including a negative entry still inside its backoff.

Source

pub async fn schema_for( &self, session: &Session, producer: &str, type_name: &str, ) -> Option<TypeSchema>

The schema for type_name as served by producer, fetching @rpc/<producer>/describe on first miss. None = the producer does not serve describe or does not describe this type — render structurally (never an error; RFC 08 §7 is a SHOULD for self-describing encodings).

A bare &Session rather than a crate::Fleet: the store was constructed with the base and composes the Fleet itself, so a caller cannot hand it a second base for the two to disagree over. Same for set_for and everything built on them.

Source

pub async fn set_for( &self, session: &Session, producer: &str, ) -> Option<Arc<SchemaSet>>

The producer’s whole served set, on the same fetch-and-cache path as schema_for (issue #51: zenctl schema show <producer> dumps the inventory, and asking type-by-type would be a different question than the one describe answers).

None = the producer does not serve describe — an honest degradation, never an error.

Source

pub fn forget(&self, producer: &str)

Forget what we learned about one producer, so the next question goes to the bus (issue #101).

The queriers are kept: they are idle routing state, and re-declaring them is exactly the cost #37 removed.

Source

pub fn forget_all(&self)

Forget every producer — the “re-ask schemas” action a frontend offers.

Covers the case the backoff cannot: a positive entry never expires, so a producer that changes its served set mid-session is otherwise read with the schemas it had at first contact.

Source

pub fn known(&self) -> Vec<(String, bool)>

Producers currently answered-for, and whether each served a set — what a frontend shows next to its re-ask button.

Source

pub fn decode( &self, schema: &TypeSchema, encoding: &WireEncoding, bytes: &[u8], ) -> Result<DecodedPayload, DecodeError>

Decode bytes under a schema, if one resolves.

Source

pub fn encode( &self, schema: &TypeSchema, value: &Value, target: &WireEncoding, ) -> Result<Vec<u8>, DecodeError>

The other direction (issue #97): a JSON value framed for the wire. The store owns the decoder table, so the write path resolves its codec exactly where the read path does — one registration, both directions.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<Source> AccessAs for Source

Source§

fn ref_as<T>(&self) -> <Source as IGuardRef<T>>::Guard<'_>
where Source: IGuardRef<T>, T: ?Sized,

Provides immutable access to a type as if it were its ABI-unstable equivalent.
Source§

fn mut_as<T>(&mut self) -> <Source as IGuardMut<T>>::GuardMut<'_>
where Source: IGuardMut<T>, T: ?Sized,

Provides mutable access to a type as if it were its ABI-unstable equivalent.
Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> AsNode<T> for T

Source§

fn as_node(&self) -> &T

Source§

impl<T> AsNodeMut<T> for T

Source§

fn as_node_mut(&mut self) -> &mut T

Source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, As> IGuardMut<As> for T
where T: Into<As>, As: Into<T>,

Source§

type GuardMut<'a> = MutAs<'a, T, As> where T: 'a

The type of the guard which will clean up the temporary after applying its changes to the original.
Source§

fn guard_mut_inner(&mut self) -> <T as IGuardMut<As>>::GuardMut<'_>

Construct the temporary and guard it through a mutable reference.
Source§

impl<T, As> IGuardRef<As> for T
where T: Into<As>, As: Into<T>,

Source§

type Guard<'a> = RefAs<'a, T, As> where T: 'a

The type of the guard which will clean up the temporary.
Source§

fn guard_ref_inner(&self) -> <T as IGuardRef<As>>::Guard<'_>

Construct the temporary and guard it through an immutable reference.
Source§

impl<T> Includes<End> for T

Source§

type Output = End

The result
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more