pub struct MessengerCore<C: RecordCodec> { /* private fields */ }Expand description
The single-writer kernel — see this module’s own doc.
Implementations§
Source§impl<C: RecordCodec> MessengerCore<C>
impl<C: RecordCodec> MessengerCore<C>
Sourcepub fn open(
records: impl IntoIterator<Item = SealedRecord>,
codec: C,
config: CoreConfig,
secrets: CoreSecrets,
_now_ms: i64,
jitter: Box<dyn Jitter>,
) -> Result<Self, MessengerError>
pub fn open( records: impl IntoIterator<Item = SealedRecord>, codec: C, config: CoreConfig, secrets: CoreSecrets, _now_ms: i64, jitter: Box<dyn Jitter>, ) -> Result<Self, MessengerError>
Rebuilds a core from whatever a shell already read back from
durable storage (records, possibly empty for a brand-new device),
config, secrets (caller-supplied CoreSecrets: store_seal_key
is consumed by MessengerCore::open_sealed before it reaches here,
and backup_key is not read by this kernel), and a jitter source for
crate::outgoing_queue::OutgoingQueue’s own retry backoff. now_ms
is accepted for API symmetry with every other entry point (this
crate’s own “no clock inside” rule) but not read by anything in this
piece’s own restore logic yet — timeline content itself is never
persisted (re-fetched off the next /sync/back-page instead, this
module’s own doc), so there is nothing time-sensitive to restore
here before a later piece needs one.
Sourcepub fn releasable_requests(&mut self, now_ms: i64) -> Vec<OutgoingRequest>
pub fn releasable_requests(&mut self, now_ms: i64) -> Vec<OutgoingRequest>
A shell calls this once per tick, executes each, and feeds the
result back via MessengerCore::on_response/
MessengerCore::on_transport_error. Also where the next /sync
request is minted, if none is currently outstanding (this module’s
own doc).
One-shot per request: never discard a non-empty result. Every
OutgoingRequest this call returns is marked in flight by
crate::outgoing_queue::OutgoingQueue::releasable as a side
effect of being returned — it will not be offered again until a
matching MessengerCore::on_response/
MessengerCore::on_transport_error call clears that flag. A
caller that calls this method purely to trigger the mint side
effect (e.g. to force a freshly-dirtied /sync request’s own flush
epoch open before deciding whether to act) and then throws the
return value away strands every request in that batch permanently
in flight, since nothing else will ever release it. Call this
exactly once per tick, and always drive every request it returns
through to a response.
Sourcepub fn on_response(
&mut self,
request_id: RequestId,
resp: HttpResponseDescriptor,
now_ms: i64,
) -> Vec<MessengerEvent>
pub fn on_response( &mut self, request_id: RequestId, resp: HttpResponseDescriptor, now_ms: i64, ) -> Vec<MessengerEvent>
Feeds one HTTP response back in, keyed by the id the original
OutgoingRequest carried. Returns whatever became visible as a
direct result of processing it (equivalent to calling
MessengerCore::events immediately afterwards — there is exactly
one underlying event queue behind both).
Sourcepub fn on_transport_error(&mut self, request_id: &RequestId, now_ms: i64)
pub fn on_transport_error(&mut self, request_id: &RequestId, now_ms: i64)
Feeds a transport-level failure back in (a timeout, a connection
reset, …) — always resolves to a retry with this core’s own
backoff (crate::outgoing_queue’s own doc); a no-op if request_id
is not (or no longer) pending.
Sourcepub fn take_flush_batch(&mut self) -> Option<FlushBatch>
pub fn take_flush_batch(&mut self) -> Option<FlushBatch>
Drains everything dirtied since the previous call into one
FlushBatch for a shell to write durably.
Sourcepub fn events(&mut self) -> Vec<MessengerEvent>
pub fn events(&mut self) -> Vec<MessengerEvent>
Drains every MessengerEvent queued since the last call to this
method or to MessengerCore::on_response.
Sourcepub fn take_ingest_error(&mut self) -> Option<String>
pub fn take_ingest_error(&mut self) -> Option<String>
The last response this core failed to ingest, once (cleared by
reading it) – see the ingest_error field’s own doc.
Sourcepub fn change_counter(&self) -> u64
pub fn change_counter(&self) -> u64
Monotonically increasing count of visible changes — a cheap
“did anything change at all since I last checked” signal for a
provider that only wants to know whether to re-read its snapshot
getters, without keeping its own copy of every MessengerEvent.
Sourcepub fn room_ids(&self) -> impl Iterator<Item = &RoomId>
pub fn room_ids(&self) -> impl Iterator<Item = &RoomId>
Every room this core currently holds state for.
Sourcepub fn room_state(&self, room_id: &RoomId) -> Option<&RoomState>
pub fn room_state(&self, room_id: &RoomId) -> Option<&RoomState>
room_id’s current state, if this core has one.
Sourcepub fn timeline(&self, room_id: &RoomId) -> Option<&Timeline>
pub fn timeline(&self, room_id: &RoomId) -> Option<&Timeline>
room_id’s current timeline, if this core has one.
Sourcepub fn room_kind(&self, room_id: &RoomId) -> Option<RoomKind>
pub fn room_kind(&self, room_id: &RoomId) -> Option<RoomKind>
room_id’s derived RoomKind (plan manager decision #5’s DM/
channel/group precedence), using this core’s current global
m.direct account data.
Sourcepub fn typing_users(&self, room_id: &RoomId) -> &[UserId]
pub fn typing_users(&self, room_id: &RoomId) -> &[UserId]
Every user currently typing in room_id, per the most recent
/sync ephemeral batch — empty if none, or if this core has never
seen a typing event for this room.
Sourcepub fn receipts(&self, room_id: &RoomId) -> Option<&ReceiptContent>
pub fn receipts(&self, room_id: &RoomId) -> Option<&ReceiptContent>
room_id’s most recently received m.receipt account data, if any.
Sourcepub fn room_account_data(
&self,
room_id: &RoomId,
event_type: &str,
) -> Option<&Value>
pub fn room_account_data( &self, room_id: &RoomId, event_type: &str, ) -> Option<&Value>
One piece of room_id’s room-scoped account data (e.g.
"m.fully_read"), if this core has seen one.
Sourcepub fn global_account_data(&self, event_type: &str) -> Option<&Value>
pub fn global_account_data(&self, event_type: &str) -> Option<&Value>
One piece of this account’s own global account data, if this core has seen one.
Sourcepub fn key_request_count(&self) -> usize
pub fn key_request_count(&self) -> usize
How many missing Megolm sessions this process has already requested.
Sourcepub fn user_id(&self) -> &UserId
pub fn user_id(&self) -> &UserId
This account’s own user id, exactly as configured at
MessengerCore::open – a UI-facing adapter needs this to tell
its own account apart from every other room member (a DM’s peer, a
reaction’s by_me, a typing-user list minus self, …).
Sourcepub fn has_tracked_device(&self, user_id: &UserId) -> bool
pub fn has_tracked_device(&self, user_id: &UserId) -> bool
Whether this core currently has at least one verified device on
file for user_id (/keys/query results already persisted by
crate::crypto::device_tracker::DeviceTracker) – a UI-facing
adapter’s own “has a messaging key” check for a member list, without
duplicating that module’s storage format.
Sourcepub fn public_rooms_result(&self) -> &[PublicRoomsResultEntry]
pub fn public_rooms_result(&self) -> &[PublicRoomsResultEntry]
The latest MessengerCommand::SearchPublicRooms result set, empty
until one has landed.
Sourcepub fn user_search_result(&self) -> &[UserDirectoryResultEntry]
pub fn user_search_result(&self) -> &[UserDirectoryResultEntry]
The latest MessengerCommand::SearchUsers result set, empty until
one has landed.
Sourcepub fn send_failure_reason(&self, txn_id: &TxnId) -> Option<&str>
pub fn send_failure_reason(&self, txn_id: &TxnId) -> Option<&str>
The Matrix errcode a failed send (txn_id) ended with, if
txn_id currently names a crate::room::timeline::SendState::Failed
send this core is still tracking — None for a send that never
failed, already succeeded, or that this core has never seen.
Sourcepub fn dispatch(
&mut self,
cmd: MessengerCommand,
now_ms: i64,
) -> Result<(), MessengerError>
pub fn dispatch( &mut self, cmd: MessengerCommand, now_ms: i64, ) -> Result<(), MessengerError>
The “in” edge — mailbox command (single-writer-core doctrine’s Law
3). See MessengerCommand’s own doc for every variant this piece
implements. now_ms is this call’s own clock reading (this crate’s
“no clock inside” rule) — used for a fresh send’s local-echo
timestamp, MessengerCommand::SetTyping’s debounce window, and
Megolm rotation timing.
Sourcepub fn pull_latest_page(
&mut self,
room_id: RoomId,
) -> Result<(), MessengerError>
pub fn pull_latest_page( &mut self, room_id: RoomId, ) -> Result<(), MessengerError>
One backward page from the tip, not from the stored sync token. Used when a push names an event the timeline does not have as text.
Sourcepub fn decrypt_loaded_timeline(&mut self)
pub fn decrypt_loaded_timeline(&mut self)
Decrypts Megolm rows already on the timeline. pending_decrypt is
memory-only, so a restarted client still holds the ciphertext and
would otherwise never turn it into text the leader trigger can see.
Sourcepub fn republish_device_keys(&mut self)
pub fn republish_device_keys(&mut self)
Asks for the device identity keys to be published again with the next sync. See
crate::crypto::account::OlmAccountState::forget_published_device_keys.
Source§impl MessengerCore<SealedRecordCodec>
impl MessengerCore<SealedRecordCodec>
Sourcepub fn open_sealed(
records: impl IntoIterator<Item = SealedRecord>,
secrets: CoreSecrets,
config: CoreConfig,
now_ms: i64,
jitter: Box<dyn Jitter>,
) -> Result<Self, MessengerError>
pub fn open_sealed( records: impl IntoIterator<Item = SealedRecord>, secrets: CoreSecrets, config: CoreConfig, now_ms: i64, jitter: Box<dyn Jitter>, ) -> Result<Self, MessengerError>
The production entry point (M14): opens a core whose store seals
every record with AES-256-GCM under secrets.store_seal_key — the
constructor a shell calls, in place of the generic
MessengerCore::open this crate’s own tests use with
[crate::store::InsecurePlainCodecForTests].
Fails with MessengerError::Crypto if secrets.store_seal_key is
None. The caller supplies that key. There is no unsealed fallback
here by design (an unsealed messenger record store is exactly what
SealedRecordCodec exists to keep off disk).