pub struct AttachStorageHandle<T> { /* private fields */ }Expand description
Handle to an attach-storage subscription. Call
AttachStorageHandle::detach to dispose it (no RAII — D246 r3).
Generic over T (next batch 2026-05-21) — the handle retains
shared references to the sinks so AttachStorageHandle::flush_all
can drive their flush() methods. Callers wire
interval(debounce_ms) → handle.flush_all() (Option B per D171
precedent — mirrors graphrefly_storage::StorageHandle::flush_all).
Implementations§
Source§impl<T> AttachStorageHandle<T>
impl<T> AttachStorageHandle<T>
Sourcepub fn detach(&mut self, core: &Core)
pub fn detach(&mut self, core: &Core)
Synchronously dispose the attach-storage subscription. Owner-invoked.
Sourcepub fn flush_all(&self) -> Result<(), Box<dyn Error + Send + Sync>>
pub fn flush_all(&self) -> Result<(), Box<dyn Error + Send + Sync>>
F9 parity — drive every sink’s flush() synchronously.
Returns the first error encountered (with a sink[N] flush:
prefix for diagnostics); subsequent sinks are NOT attempted
after a failure (matches graphrefly_storage::StorageHandle::flush_all).
Callers wire this from a reactive timer subgraph; the handle
owns no internal timer (no tokio in graphrefly-structures).
Caller obligation (D271 QA EC-2): callers MUST NOT hold a
lock that any sink’s flush() impl might try to acquire.
flush_all calls each sink synchronously and holds no internal
lock during the call, so a sink that re-enters a caller-held
lock would deadlock. Real-world sinks (graphrefly-storage’s
AppendLogStorage::flush is the canonical example) take only
their own internal locks — wiring flush_all from a reactive
timer subgraph is therefore deadlock-free by construction.