Skip to main content

DurableStore

Trait DurableStore 

pub trait DurableStore {
Show 18 methods // Required methods fn namespace(&self) -> &str; fn read(&self, key: &StorageKey) -> Result<Option<Stored>, StoreError>; fn write( &self, key: &StorageKey, op: WriteOp, writer: Option<&[u8]>, ) -> Result<Revision, StoreError>; fn durability(&self, key: &StorageKey, revision: Revision) -> Durability; fn flush(&self, key: Option<&StorageKey>) -> Result<(), StoreError>; fn wake_when_settled( &self, key: &StorageKey, wake: Arc<dyn Fn() + Send + Sync>, ) -> SettleWatch; fn lease(&self, key: &StorageKey) -> Result<Box<dyn Any>, StoreError>; fn lease_shared(&self, key: &StorageKey) -> Result<SharedLease, StoreError>; fn claim( &self, key: &StorageKey, claimant: &str, ) -> Result<bool, StoreError>; // Provided methods fn flush_without_waiting(&self, key: &StorageKey) -> Result<(), StoreError> { ... } fn flush_where_allowed(&self, key: &StorageKey) -> Result<(), StoreError> { ... } fn is_settled(&self, key: &StorageKey) -> bool { ... } fn declined_waiting_here(&self) -> bool { ... } fn records( &self, package: &str, workspace: &str, ) -> Result<Vec<String>, StoreError> { ... } fn workspace_indexes(&self) -> Result<Vec<(String, String)>, StoreError> { ... } fn local_path(&self, _key: &StorageKey) -> Option<PathBuf> { ... } fn write_hint( &self, _key: &StorageKey, _hint: &[u8], ) -> Result<(), StoreError> { ... } fn read_hint(&self, _key: &StorageKey) -> Option<Vec<u8>> { ... }
}
Expand description

Keyed, ordered, honestly-acknowledged storage.

A store is shared by every owner in one profile, so each method takes &self. Writes to one key apply in the order they were accepted.

Required Methods§

fn namespace(&self) -> &str

A stable identity for this profile’s storage. Two stores with the same namespace address the same data; history and collaboration use it to tell profiles apart, never to find files.

fn read(&self, key: &StorageKey) -> Result<Option<Stored>, StoreError>

The key’s current value, including accepted writes not yet durable. None when nothing has ever been stored.

fn write( &self, key: &StorageKey, op: WriteOp, writer: Option<&[u8]>, ) -> Result<Revision, StoreError>

Accept a write without waiting for it to commit. writer, when given, replaces the identity stored beside the key. An implementation may refuse writes to a key the caller has not leased.

§Errors

Refuses an invalid or unleased key, or a store that cannot accept more.

fn durability(&self, key: &StorageKey, revision: Revision) -> Durability

Whether the write that returned revision for key has committed. Never blocks.

fn flush(&self, key: Option<&StorageKey>) -> Result<(), StoreError>

Make everything read from or accepted for key (or every key) durable where the store can do so itself, and report whether it now is. A store that depends on its host returns [StoreError::Pending] instead of blocking.

§Errors

Reports the latest failed write, or writes still awaiting their host.

fn wake_when_settled( &self, key: &StorageKey, wake: Arc<dyn Fn() + Send + Sync>, ) -> SettleWatch

Call wake once, from any thread, when every write accepted for key and every sync asked for it before this call has committed or failed: how a window still showing “Saving…” hears that it is done without asking again and again. Never called at once: when nothing is outstanding the answer is [SettleWatch::Settled]. The same wake (waiting::same_wake) armed twice is called once.

Every store answers it: a window showing “Saving…” has no other way to learn the write landed, and never polls for it.

fn lease(&self, key: &StorageKey) -> Result<Box<dyn Any>, StoreError>

Become the key’s only writer until the returned lease is dropped.

§Errors

[StoreError::Busy] when another owner, in this process or another, already holds the key.

fn lease_shared(&self, key: &StorageKey) -> Result<SharedLease, StoreError>

Join the key’s shared writers. Shared holders coexist with each other and exclude an exclusive lease, and it them.

§Errors

[StoreError::Busy] while an exclusive lease is held; an invalid key.

fn claim(&self, key: &StorageKey, claimant: &str) -> Result<bool, StoreError>

Grant custody of key to exactly one claimant, durably: the first claim wins, and the same claimant may claim again (to resume after a crash). Used to let exactly one successor adopt a workspace record under a new identity. true when claimant holds custody.

§Errors

A key the store cannot claim, or a failure recording the claim.

Provided Methods§

fn flush_without_waiting(&self, key: &StorageKey) -> Result<(), StoreError>

Self::flush for a caller that must not wait on storage (a UI thread): start making everything read from or accepted for key durable and return at once. Ok when it already is; otherwise [StoreError::Pending], the work left to the store’s own thread, and Self::is_settled turns true when it has finished. A store with no thread of its own waits, as Self::flush does.

§Errors

The latest failed write, or [StoreError::Pending].

fn flush_where_allowed(&self, key: &StorageKey) -> Result<(), StoreError>

Self::flush where this thread may wait on storage; on a thread that must not (waiting::forbid_on_this_thread: a frame loop), Self::flush_without_waiting, whose [StoreError::Pending] means the store’s own thread is committing and Self::durability tells how it went.

§Errors

As the call it makes.

fn is_settled(&self, key: &StorageKey) -> bool

Whether everything read from or accepted for key is on stable storage now. Does not wait where the store has a thread of its own.

fn declined_waiting_here(&self) -> bool

Whether a lease or read the calling thread makes may answer [StoreError::Opening]: on a thread that must not wait on storage (waiting, a frame loop), Self::lease, Self::lease_shared and Self::read of a key the store has not opened for this thread answer it while the store’s own thread opens or reads the key, and that thread calls the caller’s wake once it has: asked again, they then wait on nothing. Reads of a key this thread leased answer what was read for the lease, with the writes accepted since, and Self::read_hint answers only a hint already read. Other threads are unaffected. A store with no thread of its own works in place, and answers false.

fn records( &self, package: &str, workspace: &str, ) -> Result<Vec<String>, StoreError>

The record component of every [StorageKey::Record] of package in workspace that holds stored bytes, sorted. Lets a host find records it can no longer name: an app that used to keep a record per window and now keeps one per workspace adopts its windows’ records. A store that cannot enumerate its keys answers with none.

fn workspace_indexes(&self) -> Result<Vec<(String, String)>, StoreError>

Every [StorageKey::WorkspaceIndex] the store holds, as its package and workspace components, sorted. Lets a host read which records the workspaces on this device keep without knowing their names first. A store that cannot enumerate its keys answers with none.

fn local_path(&self, _key: &StorageKey) -> Option<PathBuf>

Where a host that keeps the key in a local file keeps it. Only for diagnostics and tools that work on that file; None elsewhere.

fn write_hint(&self, _key: &StorageKey, _hint: &[u8]) -> Result<(), StoreError>

Keep hint beside the key’s value on this device: bytes a caller derived from a value it wrote, to make the next read of that value cheaper to use. A hint is never part of the value, never leaves the device and may be dropped at any time, so the caller must recognise the value it was made for itself; a store that keeps none drops it. The key must be leased, as for Self::write.

fn read_hint(&self, _key: &StorageKey) -> Option<Vec<u8>>

The hint last kept beside the key by Self::write_hint, if the store still has one.

Implementations on Foreign Types§

§

impl DurableStore for FsStore

§

fn records( &self, package: &str, workspace: &str, ) -> Result<Vec<String>, StoreError>

Records whose document file holds committed bytes. A write still in its debounce window is not listed until it commits.

§

fn write_hint(&self, key: &StorageKey, hint: &[u8]) -> Result<(), StoreError>

Kept in the record’s directory, which only this device writes and never syncs. Written at once, unsynced: a hint lost to a crash, or written ahead of a replacement that then fails, names bytes the document no longer holds and the reader ignores it.

§

fn namespace(&self) -> &str

§

fn read(&self, key: &StorageKey) -> Result<Option<Stored>, StoreError>

§

fn write( &self, key: &StorageKey, op: WriteOp, writer: Option<&[u8]>, ) -> Result<Revision, StoreError>

§

fn durability(&self, key: &StorageKey, revision: Revision) -> Durability

§

fn flush(&self, key: Option<&StorageKey>) -> Result<(), StoreError>

§

fn flush_without_waiting(&self, key: &StorageKey) -> Result<(), StoreError>

§

fn is_settled(&self, key: &StorageKey) -> bool

§

fn wake_when_settled( &self, key: &StorageKey, wake: Arc<dyn Fn() + Send + Sync>, ) -> SettleWatch

§

fn lease(&self, key: &StorageKey) -> Result<Box<dyn Any>, StoreError>

§

fn lease_shared(&self, key: &StorageKey) -> Result<SharedLease, StoreError>

§

fn declined_waiting_here(&self) -> bool

§

fn claim(&self, key: &StorageKey, claimant: &str) -> Result<bool, StoreError>

§

fn workspace_indexes(&self) -> Result<Vec<(String, String)>, StoreError>

§

fn local_path(&self, key: &StorageKey) -> Option<PathBuf>

§

fn read_hint(&self, key: &StorageKey) -> Option<Vec<u8>>

Implementors§

§

impl DurableStore for MemoryStore