Skip to main content

AttachmentRootSet

Trait AttachmentRootSet 

Source
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 Self: 'async_trait,
             'life0: '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 Self: 'async_trait,
             'life0: 'async_trait,
             'life1: '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§

Source

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 Self: 'async_trait, 'life0: '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§

Source

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 Self: 'async_trait, 'life0: 'async_trait, 'life1: '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§

Source§

impl<T: SessionStoreFactory + ?Sized> AttachmentRootSet for T

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.