pub trait AttachmentRootSet: Send + Sync {
// Required method
fn live_attachment_refs<'life0, 'async_trait>(
&'life0 self,
intent_grace_cutoff_epoch_ms: u64,
) -> Pin<Box<dyn Future<Output = Result<BTreeSet<AttachmentId>, StoreError>> + Send + 'async_trait>>
where 'life0: 'async_trait,
Self: 'async_trait;
// Provided method
fn has_live_attachment_ref<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 AttachmentId,
intent_grace_cutoff_epoch_ms: u64,
) -> Pin<Box<dyn Future<Output = Result<bool, StoreError>> + Send + 'async_trait>>
where 'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait { ... }
}Expand description
A source of the live attachment root set: every attachment ref (intent or committed) across ALL sessions a store factory owns. Intents count as refs, so an in-flight write is never mistaken for garbage.
Implemented by session-store factories, which own the full set of sessions: a global manifest table answers in one query (Postgres); a per-session database topology answers by iterating the factory’s session databases at sweep time (SQLite); an in-memory factory answers from its live stores.
Required Methods§
Sourcefn live_attachment_refs<'life0, 'async_trait>(
&'life0 self,
intent_grace_cutoff_epoch_ms: u64,
) -> Pin<Box<dyn Future<Output = Result<BTreeSet<AttachmentId>, StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn live_attachment_refs<'life0, 'async_trait>(
&'life0 self,
intent_grace_cutoff_epoch_ms: u64,
) -> Pin<Box<dyn Future<Output = Result<BTreeSet<AttachmentId>, StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
The live root set, reconciled against intent_grace_cutoff_epoch_ms.
A committed ref is always a root. An uncommitted intent counts as a
root only while it is younger than the cutoff; an intent whose
intent_at_epoch_ms is at or before the cutoff is a crash orphan (its
turn never committed and has aged past the grace window), so the root set
forgets it and excludes it, making its blob collectable. The cutoff is
now - grace_period_ms; callers must set the grace period larger than the
longest expected turn so a live turn’s intent is never mistaken for an
orphan (the same assumption the removed per-session sweep made).
Provided Methods§
Sourcefn has_live_attachment_ref<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 AttachmentId,
intent_grace_cutoff_epoch_ms: u64,
) -> Pin<Box<dyn Future<Output = Result<bool, StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn has_live_attachment_ref<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 AttachmentId,
intent_grace_cutoff_epoch_ms: u64,
) -> Pin<Box<dyn Future<Output = Result<bool, StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Whether a single id currently has a live root — a committed ref, or an
uncommitted intent younger than intent_grace_cutoff_epoch_ms.
Targeted counterpart to Self::live_attachment_refs for the GC lever’s
delete-time root re-check (see reclaim_unreferenced_attachments): the
full root set is snapshotted once, but a candidate blob can be re-referenced
in the narrow window between the freshness re-check and the delete, so the
sweep re-probes just that id. Unlike the snapshot, this is a read-only probe
— it must NOT reconcile (forget) aged intents. Backends answer with a single
indexed query / first-hit scan rather than materializing the whole set. The
default re-materializes the root set and tests membership.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".
Implementors§
impl<T> AttachmentRootSet for Twhere
T: SessionStoreFactory + ?Sized,
Every session-store factory is a root set: it owns all sessions, so it can
enumerate their refs. The concrete factories override
SessionStoreFactory::live_attachment_refs;
this blanket makes any of them (including dyn SessionStoreFactory) usable
as the GC lever’s root_set.