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
impl TypingRegistry
Sourcepub fn new() -> Self
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).
Sourcepub fn with_seed(seed: u64) -> Self
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.
Sourcepub fn set_typing(
&self,
room_id: &str,
user_id: i64,
typing: bool,
timeout_ms: u64,
now: Instant,
) -> bool
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.
Sourcepub fn current_typing_gen(&self) -> u64
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.
Sourcepub fn typing_users(&self, room_id: &str, now: Instant) -> Vec<i64>
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).
Sourcepub fn typing_serial(&self, room_id: &str, now: Instant) -> u64
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.
Sourcepub fn rooms_with_expired_typing(&self, now: Instant) -> Vec<String>
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.