Struct JournaledSession
pub struct JournaledSession {
memory: InMemorySession,
log: SessionOpsBuf,
}alloc only.Expand description
A SessionState wrapper that records every mutation as a SessionOp.
The inner InMemorySession is updated immediately so that queries always
reflect the latest state. Each mutation is also appended to an internal op
log, exposed as pending_ops. The persistence layer
consumes those ops (encoding them with encode_frames for a file, or
applying them as rows for a SQL store) and then calls clear
once they are durable.
This is a sans-io building block: it knows nothing about files or async.
Fields§
§memory: InMemorySession§log: SessionOpsBufImplementations§
§impl JournaledSession
impl JournaledSession
pub const fn new() -> Self
pub const fn new() -> Self
Creates a new journaled session with an empty in-memory state.
pub const fn from_memory(memory: InMemorySession) -> Self
pub const fn from_memory(memory: InMemorySession) -> Self
Creates a journaled session wrapping an existing in-memory session.
Use this when reloading persisted state: first rebuild the
InMemorySession, then wrap it so that future mutations are recorded.
pub const fn memory(&self) -> &InMemorySession
pub const fn memory(&self) -> &InMemorySession
Borrows the inner in-memory session.
pub const fn pending_ops(&self) -> &SessionOps
pub const fn pending_ops(&self) -> &SessionOps
Borrows the ops recorded since the last clear, in
order.
The persistence layer persists these (framing them with
encode_frames for a file, or applying them as rows for a SQL store)
and then calls clear. Pair the two with a retry-safe
contract: persist first, clear only once the write succeeds, so a failed
write keeps the ops buffered for the next attempt.
pub fn clear(&mut self)
pub fn clear(&mut self)
Discards the recorded ops after they have been persisted.
Trait Implementations§
§impl Default for JournaledSession
impl Default for JournaledSession
§impl SessionState for JournaledSession
impl SessionState for JournaledSession
§fn apply(&mut self, op: SessionOp<'_>) -> Applied
fn apply(&mut self, op: SessionOp<'_>) -> Applied
§fn reset_outbox_sent_flags(&mut self)
fn reset_outbox_sent_flags(&mut self)
§fn for_each_outbox_entry(&self, f: &mut dyn FnMut(PacketId, OutboxEntry<'_>))
fn for_each_outbox_entry(&self, f: &mut dyn FnMut(PacketId, OutboxEntry<'_>))
§fn drain_outbox(
&mut self,
visit: &mut dyn FnMut(PacketId, OutboxEntry<'_>) -> DrainAction,
)
fn drain_outbox( &mut self, visit: &mut dyn FnMut(PacketId, OutboxEntry<'_>) -> DrainAction, )
DrainAction the visitor
returns: Sent marks it in-flight and was_sent;
Discard removes it;
Stop halts the walk. This is the single
outbound send path, so the visitor is the only place a publish
reaches the wire.§fn reset_in_flight(&mut self)
fn reset_in_flight(&mut self)
§fn has_pubrel_pending(&self, packet_id: PacketId) -> bool
fn has_pubrel_pending(&self, packet_id: PacketId) -> bool
true if a PUBREL is pending for packet_id (the QoS 2
publish is in the awaiting-PUBCOMP phase). Read more§fn for_each_pubrel_pending(&self, f: &mut dyn FnMut(PacketId))
fn for_each_pubrel_pending(&self, f: &mut dyn FnMut(PacketId))
§fn drain_pubrel(&mut self, visit: &mut dyn FnMut(PacketId) -> DrainAction)
fn drain_pubrel(&mut self, visit: &mut dyn FnMut(PacketId) -> DrainAction)
DrainAction. Mirrors
drain_outbox for the QoS 2 PUBREL resend.§fn has_incoming_qos2(&self, packet_id: PacketId) -> bool
fn has_incoming_qos2(&self, packet_id: PacketId) -> bool
QoS 2 packet identifier is stored (i.e.,
PUBREC was already sent for this packet ID).§fn clear_incoming_qos2(&mut self)
fn clear_incoming_qos2(&mut self)
QoS 2 packet identifiers. Read more§fn for_each_incoming_qos2(&self, f: &mut dyn FnMut(PacketId))
fn for_each_incoming_qos2(&self, f: &mut dyn FnMut(PacketId))
QoS 2 packet identifier.§fn get_filter_entry(&self, filter: &TopicFilter) -> Option<FilterEntry<'_>>
fn get_filter_entry(&self, filter: &TopicFilter) -> Option<FilterEntry<'_>>
None if it
has not been touched. Used by the client to determine the filter’s
current state before recording an UNSUBSCRIBE transition.§fn resolve_pending(
&mut self,
packet_id: PacketId,
decide: &mut dyn FnMut(FilterEntry<'_>) -> Resolution,
)
fn resolve_pending( &mut self, packet_id: PacketId, decide: &mut dyn FnMut(FilterEntry<'_>) -> Resolution, )
Subscribing or
Unsubscribing) under packet_id and applies the returned
Resolution, dropping the entry’s pending-order slot for every
decision other than Resolution::Keep.§fn for_each_active_subscription(&self, f: &mut dyn FnMut(Subscription<'_>))
fn for_each_active_subscription(&self, f: &mut dyn FnMut(Subscription<'_>))
Subscribed filter (the
application’s active subscriptions). In-flight Subscribing/
Unsubscribing entries are skipped.§fn for_each_filter_entry(&self, f: &mut dyn FnMut(FilterEntry<'_>))
fn for_each_filter_entry(&self, f: &mut dyn FnMut(FilterEntry<'_>))
§fn first_pending_group(&self) -> Option<PendingMeta>
fn first_pending_group(&self) -> Option<PendingMeta>
None
when none remain. This is a read-only peek; the caller iterates the
group’s filters
(pending_subscribe_filters /
pending_unsubscribe_filters),
enqueues the packet, then commits the group with
mark_subscription_in_flight. Read more§fn pending_subscribe_filters(
&self,
packet_id: PacketId,
) -> impl Iterator<Item = (&TopicFilter, SubscriptionOptions)>
fn pending_subscribe_filters( &self, packet_id: PacketId, ) -> impl Iterator<Item = (&TopicFilter, SubscriptionOptions)>
packet_id, in
packet order (their position in the SUBACK), each with its subscription
options. Empty unless packet_id is a pending SUBSCRIBE.§fn pending_unsubscribe_filters(
&self,
packet_id: PacketId,
) -> impl Iterator<Item = &TopicFilter>
fn pending_unsubscribe_filters( &self, packet_id: PacketId, ) -> impl Iterator<Item = &TopicFilter>
packet_id, in
packet order. Empty unless packet_id is a pending UNSUBSCRIBE.§fn mark_subscription_in_flight(&mut self, packet_id: PacketId)
fn mark_subscription_in_flight(&mut self, packet_id: PacketId)
packet_id in flight and drops the group from
the pending set, so the next
first_pending_group skips it until
reset_in_flight re-arms it. Called once
the group’s packet has been enqueued.§fn is_packet_id_in_use(&self, packet_id: PacketId) -> bool
fn is_packet_id_in_use(&self, packet_id: PacketId) -> bool
true if packet_id is currently occupied by any tracked
operation: an outbox entry, a PUBREL-pending entry, or an in-flight
SUBSCRIBE/UNSUBSCRIBE. Read more