pub struct BatchingPersist<'a> { /* private fields */ }Expand description
Wraps any handler for a bulk-sync drain loop: every callback delegates to the inner
handler, but committed messages BUFFER here instead of saving one transaction each —
the loop calls BatchingPersist::flush periodically and at stream end to land them
in batched transactions (save_messages_batch_multi).
Deferral is recoverable because the wrapper ledger (the negentropy fingerprint set) rides the flush transaction: a message lost to a crash, a stale-session drop, or a failed flush leaves its wrapper unledgered, so the next reconciliation re-delivers it.
Implementations§
Source§impl<'a> BatchingPersist<'a>
impl<'a> BatchingPersist<'a>
pub fn new(inner: &'a dyn InboundEventHandler) -> Self
Sourcepub fn buffered(&self) -> usize
pub fn buffered(&self) -> usize
How many messages are waiting — the loop’s flush-threshold probe.
Sourcepub async fn flush(&self, session: &SessionGuard) -> usize
pub async fn flush(&self, session: &SessionGuard) -> usize
Drain the buffer into batched transactions (grouped by chat, arrival order kept). On a stale session the drained messages are DROPPED, never written into the next account’s DB — their wrappers stay unledgered, so negentropy re-delivers them when the original account returns.
Sourcepub async fn try_flush(&self, session: &SessionGuard) -> Result<usize, String>
pub async fn try_flush(&self, session: &SessionGuard) -> Result<usize, String>
Self::flush, but a persist failure is distinguishable from “nothing
to write” — callers that gate follow-on effects on the ledger actually
holding the batch (reconcile-cursor births) need the difference: an
advance over an unledgered batch skips those events forever.
Trait Implementations§
Source§impl InboundEventHandler for BatchingPersist<'_>
impl InboundEventHandler for BatchingPersist<'_>
Source§fn buffer_persist(
&self,
chat_id: &str,
msg: &Message,
wrapper: Option<([u8; 32], u64)>,
) -> bool
fn buffer_persist( &self, chat_id: &str, msg: &Message, wrapper: Option<([u8; 32], u64)>, ) -> bool
true to take ownership of persisting a committed
DM/file message — the commit then SKIPS its per-message save AND its wrapper-ledger
write (wrapper = the gift-wrap’s (id_bytes, created_at); the owner MUST commit it
in the same transaction as the message row, or the message loses crash/drop
recoverability). Streaming sync loops (see BatchingPersist) buffer here and drain
many messages into one transaction. Default false keeps the per-message save.Source§fn on_dm_received(&self, chat_id: &str, msg: &Message, is_new: bool)
fn on_dm_received(&self, chat_id: &str, msg: &Message, is_new: bool)
Source§fn on_file_received(&self, chat_id: &str, msg: &Message, is_new: bool)
fn on_file_received(&self, chat_id: &str, msg: &Message, is_new: bool)
Source§fn on_reaction_received(&self, chat_id: &str, msg: &Message)
fn on_reaction_received(&self, chat_id: &str, msg: &Message)
Source§fn on_message_deleted(&self, chat_id: &str, message_id: &str)
fn on_message_deleted(&self, chat_id: &str, message_id: &str)
Source§fn on_community_invite(&self, community_id: &str)
fn on_community_invite(&self, community_id: &str)
Source§fn on_community_message(&self, chat_id: &str, msg: &Message, is_new: bool)
fn on_community_message(&self, chat_id: &str, msg: &Message, is_new: bool)
Source§fn on_community_update(&self, chat_id: &str, target_id: &str, msg: &Message)
fn on_community_update(&self, chat_id: &str, target_id: &str, msg: &Message)
target_id is the
affected message; msg is the live-updated view.Source§fn on_community_removed(&self, chat_id: &str, target_id: &str)
fn on_community_removed(&self, chat_id: &str, target_id: &str)
Source§fn on_community_presence(
&self,
chat_id: &str,
npub: &str,
joined: bool,
event_id: &str,
created_at: u64,
invited_by: Option<&str>,
invited_label: Option<&str>,
)
fn on_community_presence( &self, chat_id: &str, npub: &str, joined: bool, event_id: &str, created_at: u64, invited_by: Option<&str>, invited_label: Option<&str>, )
created_at is the authenticated inner timestamp;
invited_by/invited_label carry invite attribution when present.Source§fn on_community_typing(&self, chat_id: &str, npub: &str, until: u64)
fn on_community_typing(&self, chat_id: &str, npub: &str, until: u64)
until is the unix-secs the typer stops being active.Source§fn on_community_webxdc(
&self,
chat_id: &str,
npub: &str,
topic_id: &str,
node_addr: Option<&str>,
event_id: &str,
created_at: u64,
)
fn on_community_webxdc( &self, chat_id: &str, npub: &str, topic_id: &str, node_addr: Option<&str>, event_id: &str, created_at: u64, )
node_addr = Some advertises an Iroh node, None = peer-left.Source§fn on_community_self_removed(&self, community_id: &str)
fn on_community_self_removed(&self, community_id: &str)
Source§fn on_community_refreshed(&self, community_id: &str)
fn on_community_refreshed(&self, community_id: &str)
Source§fn on_community_dissolved(&self, community_id: &str)
fn on_community_dissolved(&self, community_id: &str)
Source§fn on_channel_keyed(
&self,
_community_id: &str,
_channel_id: &str,
_backfilled: usize,
)
fn on_channel_keyed( &self, _community_id: &str, _channel_id: &str, _backfilled: usize, )
channel_id is the 32-byte hex id. Read moreSource§fn on_subscription_ready(&self, _communities: usize)
fn on_subscription_ready(&self, _communities: usize)
listen, after the startup refresh commits —
even when communities is 0, so “subscribed to nothing” and “still
connecting” are distinguishable. Before this, messages are only
recoverable by a later sync, not live.Auto Trait Implementations§
impl<'a> !Freeze for BatchingPersist<'a>
impl<'a> !RefUnwindSafe for BatchingPersist<'a>
impl<'a> !UnwindSafe for BatchingPersist<'a>
impl<'a> Send for BatchingPersist<'a>
impl<'a> Sync for BatchingPersist<'a>
impl<'a> Unpin for BatchingPersist<'a>
impl<'a> UnsafeUnpin for BatchingPersist<'a>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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