Skip to main content

TypingRegistry

Struct TypingRegistry 

Source
pub struct TypingRegistry { /* private fields */ }
Expand description

In-memory, per-room typing indicator state (§3.6) — deliberately never written to messenger.db (see the module doc). Not related to [LiveRegistry]’s own keys; a caller that gets changed == true back from Self::set_typing (or a non-empty room list back from Self::rooms_with_expired_typing) is the one that decides which LiveRegistry keys to wake for it.

Implementations§

Source§

impl TypingRegistry

Source

pub fn new() -> Self

A fresh registry whose typing generation starts at 0 — this codebase’s own tests use this (deterministic small values are easy to assert against); production boot uses Self::with_seed instead (see that constructor’s own doc for why).

Source

pub fn with_seed(seed: u64) -> Self

A fresh registry whose typing generation starts at seed (the FIRST effective change stamps seed + 1, matching Self::new’s own “first change stamps 1” behavior when seed == 0). Production boot (main.rs) seeds this from the current Unix time in milliseconds — see the module doc’s “The typing generation is GLOBAL, not per-room” section: an in-memory counter starting at 0 on every restart can under-report a typing change to a client still holding a higher-typing_gen token from before that restart. Seeding from a wall-clock reading that only ever increases makes a POST-restart seed reliably higher than anything a PRE-restart process could ever have reached (an AtomicU64 counter incrementing once per typing change, even at an implausible sustained rate, cannot climb into the same range as milliseconds-since-1970 within any real process lifetime) — closing the under-reporting gap Self::current_typing_gen’s own doc used to accept as a known limitation.

Source

pub fn set_typing( &self, room_id: &str, user_id: i64, typing: bool, timeout_ms: u64, now: Instant, ) -> bool

Apply one PUT /rooms/{roomId}/typing/{userId} call. timeout_ms (only meaningful when typing == true) is clamped to [TYPING_MAX_TIMEOUT_MS]. Returns whether this call actually changed who counts as typing in room_id — false for a throttled repeat true (§3.6), a refresh of an already-active true, or a false for a user who was not counted as typing — callers should skip waking anyone when this returns false.

Source

pub fn current_typing_gen(&self) -> u64

The current global typing generation — every effective typing change across every room takes its own room’s [RoomTyping::serial] from this SAME counter (see the module doc), so “room serial > token’s typing_gen” identifies exactly the rooms whose typing changed since that token was issued. 0 means no typing change has EVER been accepted by this registry instance — a fresh boot, or simply an idle server; a token carrying typing_gen: 0 (the bare s{stream_id} legacy form routes::matrix::sync_token still accepts, or a token issued before this server ever saw a single typing PUT) never wrongly suppresses a real future change, since every real change stamps a value >= 1.

In-memory only, like every other fact this registry holds — a plain TypingRegistry::new() restarts this counter at 0 on every process restart. Production boot avoids the resulting under-report risk (a token issued before a restart carrying a typing_gen LARGER than anything a freshly-zeroed registry has assigned yet) by constructing via Self::with_seed instead, seeded from a wall-clock reading that is always higher than any pre-restart value — see that constructor’s own doc.

Source

pub fn typing_users(&self, room_id: &str, now: Instant) -> Vec<i64>

Current (non-expired) typers in room_id, sorted for a deterministic response — expired entries are dropped lazily as a side effect. Empty (including for a room this registry has never heard of) rather than an error — matches m.typing’s own “no event at all if nobody is typing” convention (§3.6).

Source

pub fn typing_serial(&self, room_id: &str, now: Instant) -> u64

room_id’s current typing serial — stamped from the SAME global counter Self::current_typing_gen reads (see the module doc) on every effective change; 0 for a room this registry has never heard of, or one whose typing set has never actually changed since boot. Reaps expired entries first, so this is never stale relative to now. routes::matrix::sync’s own per-room condition is is_initial || typing_serial(room, now) > token.typing_gen.

Source

pub fn rooms_with_expired_typing(&self, now: Instant) -> Vec<String>

Sweep every room, reaping any typing flag that has timed out since it was last touched, and return the room_ids whose typing set changed as a result. A periodic tick (or the /sync path itself) calls this and wakes the returned rooms’ members — without it, a member who stops typing and never sends another /sync-triggering action would never have their typing flag cleared for anyone currently blocked in a long poll.

Trait Implementations§

Source§

impl Default for TypingRegistry

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

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> 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<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

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> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. 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, !>

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