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
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>
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>
fn write( &self, key: &StorageKey, op: WriteOp, writer: Option<&[u8]>, ) -> Result<Revision, StoreError>
fn durability(&self, key: &StorageKey, revision: Revision) -> Durability
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>
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
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>
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 claim(&self, key: &StorageKey, claimant: &str) -> Result<bool, StoreError>
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>
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>
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
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
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>
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>
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>
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>
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>>
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
impl DurableStore for FsStore
§fn records(
&self,
package: &str,
workspace: &str,
) -> Result<Vec<String>, StoreError>
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>
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.