pub struct Store {
pub path: PathBuf,
/* private fields */
}Expand description
An append-only event stream backed by a directory on disk.
Open one with new. Store is cheaply Cloneable: every
clone shares the same underlying database, broadcast channel, and
content-addressed store, so clone it freely across tasks and threads instead
of wrapping it in an Arc.
See the module docs for the topic and retention model.
Fields§
§path: PathBufDirectory backing this store (the path passed to new).
Implementations§
Source§impl Store
impl Store
Sourcepub fn new(path: PathBuf) -> Result<Store, StoreError>
pub fn new(path: PathBuf) -> Result<Store, StoreError>
Open the store at path, creating the directory layout if it does not
exist. Spawns a background worker that garbage-collects expired frames.
§Errors
Returns StoreError::Locked if another process already holds the
store open, or StoreError::Other for any other database error.
use xs::Store;
let store = Store::new("./clipboard-store".into())?;Sourcepub async fn wait_for_gc(&self)
pub async fn wait_for_gc(&self)
Wait until the background garbage-collection worker has processed every task queued so far. Useful in tests to observe TTL eviction deterministically.
Sourcepub async fn read(&self, options: ReadOptions) -> Receiver<Frame>
pub async fn read(&self, options: ReadOptions) -> Receiver<Frame>
Read frames into an async channel according to options.
By default this replays matching historical frames oldest-first and then
closes the channel. With FollowOption::On it instead keeps the
channel open and streams new appends as they arrive. When following, a
single ephemeral xs.threshold frame is emitted to mark the boundary
between replayed history and live events.
The returned Receiver is bounded;
dropping it stops the read. For a blocking, non-async caller use
read_sync.
use xs::{Store, ReadOptions, FollowOption};
let mut rx = store
.read(ReadOptions::builder().follow(FollowOption::On).build())
.await;
while let Some(frame) = rx.recv().await {
if frame.topic == "xs.threshold" {
// caught up to live; everything after this is new
continue;
}
println!("{} {}", frame.id, frame.topic);
}Sourcepub fn read_sync(
&self,
options: ReadOptions,
) -> impl Iterator<Item = Frame> + '_
pub fn read_sync( &self, options: ReadOptions, ) -> impl Iterator<Item = Frame> + '_
Replay matching historical frames as a blocking iterator.
This honours the topic, from, after, limit, and last parts of
ReadOptions but ignores follow: it never
streams live appends. Use read when you need to follow.
use xs::{Store, ReadOptions};
let opts = ReadOptions::builder().topic("clip.*".to_string()).last(10).build();
for frame in store.read_sync(opts) {
println!("{} {}", frame.id, frame.topic);
}Sourcepub fn nu_modules_at(&self, as_of: &Scru128Id) -> HashMap<String, Integrity>
pub fn nu_modules_at(&self, as_of: &Scru128Id) -> HashMap<String, Integrity>
Returns the current module state as of a given point in the stream.
Scans all frames up to (and including) as_of and returns a mapping of
module name to CAS hash for the latest frame on each xs.module.<name>
topic.
Resolve the set of registered Nushell modules as of a given frame ID.
Scans xs.module.<name> frames up to and including as_of and returns a
map from module name to the content hash of its latest definition. Used
by the scripting runtime; rarely needed when embedding the store
directly.
Sourcepub fn get(&self, id: &Scru128Id) -> Option<Frame>
pub fn get(&self, id: &Scru128Id) -> Option<Frame>
Fetch a single frame by ID, or None if no such frame exists.
Sourcepub fn remove(&self, id: &Scru128Id) -> Result<(), Error>
pub fn remove(&self, id: &Scru128Id) -> Result<(), Error>
Delete a frame and its topic index entries. Removing a frame that does
not exist is a no-op and returns Ok(()).
This removes the stream entry only; any payload bytes in the content-addressed store are left in place.
Sourcepub async fn cas_reader(&self, hash: Integrity) -> Result<Reader>
pub async fn cas_reader(&self, hash: Integrity) -> Result<Reader>
Open a streaming reader for the payload identified by hash.
Sourcepub fn cas_reader_sync(&self, hash: Integrity) -> Result<SyncReader>
pub fn cas_reader_sync(&self, hash: Integrity) -> Result<SyncReader>
Blocking variant of cas_reader.
Sourcepub async fn cas_writer(&self) -> Result<Writer>
pub async fn cas_writer(&self) -> Result<Writer>
Open a streaming writer; finish it to obtain the payload’s integrity hash.
Sourcepub fn cas_writer_sync(&self) -> Result<SyncWriter>
pub fn cas_writer_sync(&self) -> Result<SyncWriter>
Blocking variant of cas_writer.
Sourcepub async fn cas_insert(&self, content: impl AsRef<[u8]>) -> Result<Integrity>
pub async fn cas_insert(&self, content: impl AsRef<[u8]>) -> Result<Integrity>
Store content and return its integrity hash, ready to attach to a
Frame::hash.
Sourcepub fn cas_insert_sync(&self, content: impl AsRef<[u8]>) -> Result<Integrity>
pub fn cas_insert_sync(&self, content: impl AsRef<[u8]>) -> Result<Integrity>
Blocking variant of cas_insert.
Sourcepub async fn cas_insert_bytes(&self, bytes: &[u8]) -> Result<Integrity>
pub async fn cas_insert_bytes(&self, bytes: &[u8]) -> Result<Integrity>
Convenience wrapper over cas_insert for a byte slice.
Sourcepub fn cas_insert_bytes_sync(&self, bytes: &[u8]) -> Result<Integrity>
pub fn cas_insert_bytes_sync(&self, bytes: &[u8]) -> Result<Integrity>
Blocking variant of cas_insert_bytes.
Sourcepub async fn cas_read(&self, hash: &Integrity) -> Result<Vec<u8>>
pub async fn cas_read(&self, hash: &Integrity) -> Result<Vec<u8>>
Read back the full payload for hash into a Vec<u8>.
Sourcepub fn insert_frame(&self, frame: &Frame) -> Result<(), Error>
pub fn insert_frame(&self, frame: &Frame) -> Result<(), Error>
Persist a frame exactly as given, including its existing
id, without broadcasting it to live readers or scheduling
TTL garbage collection.
Most callers want append instead, which assigns a
fresh ID, handles ephemeral and Last retention, and notifies
subscribers. Use insert_frame only when you are reconstructing a stream
with predetermined IDs (for example when restoring a backup).
Sourcepub fn append(&self, frame: Frame) -> Result<Frame, Error>
pub fn append(&self, frame: Frame) -> Result<Frame, Error>
Append a frame to the stream and return it with its freshly assigned
id.
This is the primary write path. It:
- assigns a new time-sortable ID (overwriting any ID on the input);
- validates the topic (see
validate_topic); - persists the frame, unless its
TTLisTTL::Ephemeral, in which case it is only broadcast to live readers; - schedules garbage collection for
TTL::Lastretention; - broadcasts the frame to everyone currently in a following
read.
Appends are serialized internally, so frames are assigned IDs and delivered to subscribers in a consistent order.
§Errors
Returns an error if the topic is invalid or the underlying write fails.
use xs::{Store, Frame, TTL};
let hash = store.cas_insert("hello clipboard").await?;
let frame = store.append(
Frame::builder("clip.add").hash(hash).ttl(TTL::Last(100)).build(),
)?;
println!("appended {}", frame.id);Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for Store
impl !UnwindSafe for Store
impl Freeze for Store
impl Send for Store
impl Sync for Store
impl Unpin for Store
impl UnsafeUnpin for Store
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoSpanned for T
impl<T> IntoSpanned for T
Source§impl<D> OwoColorize for D
impl<D> OwoColorize for D
Source§fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
Source§fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
Source§fn black(&self) -> FgColorDisplay<'_, Black, Self>
fn black(&self) -> FgColorDisplay<'_, Black, Self>
Source§fn on_black(&self) -> BgColorDisplay<'_, Black, Self>
fn on_black(&self) -> BgColorDisplay<'_, Black, Self>
Source§fn red(&self) -> FgColorDisplay<'_, Red, Self>
fn red(&self) -> FgColorDisplay<'_, Red, Self>
Source§fn on_red(&self) -> BgColorDisplay<'_, Red, Self>
fn on_red(&self) -> BgColorDisplay<'_, Red, Self>
Source§fn green(&self) -> FgColorDisplay<'_, Green, Self>
fn green(&self) -> FgColorDisplay<'_, Green, Self>
Source§fn on_green(&self) -> BgColorDisplay<'_, Green, Self>
fn on_green(&self) -> BgColorDisplay<'_, Green, Self>
Source§fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>
fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>
Source§fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>
fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>
Source§fn blue(&self) -> FgColorDisplay<'_, Blue, Self>
fn blue(&self) -> FgColorDisplay<'_, Blue, Self>
Source§fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>
fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>
Source§fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>
fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>
Source§fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
Source§fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>
fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>
Source§fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>
fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>
Source§fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>
fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>
Source§fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>
fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>
Source§fn white(&self) -> FgColorDisplay<'_, White, Self>
fn white(&self) -> FgColorDisplay<'_, White, Self>
Source§fn on_white(&self) -> BgColorDisplay<'_, White, Self>
fn on_white(&self) -> BgColorDisplay<'_, White, Self>
Source§fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
Source§fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
Source§fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
Source§fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
Source§fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
Source§fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
Source§fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
Source§fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
Source§fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
Source§fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
Source§fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
Source§fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
Source§fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
Source§fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
Source§fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
Source§fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
Source§fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
Source§fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
Source§fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
Source§fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
Source§fn bold(&self) -> BoldDisplay<'_, Self>
fn bold(&self) -> BoldDisplay<'_, Self>
Source§fn dimmed(&self) -> DimDisplay<'_, Self>
fn dimmed(&self) -> DimDisplay<'_, Self>
Source§fn italic(&self) -> ItalicDisplay<'_, Self>
fn italic(&self) -> ItalicDisplay<'_, Self>
Source§fn underline(&self) -> UnderlineDisplay<'_, Self>
fn underline(&self) -> UnderlineDisplay<'_, Self>
Source§fn blink(&self) -> BlinkDisplay<'_, Self>
fn blink(&self) -> BlinkDisplay<'_, Self>
Source§fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
Source§fn reversed(&self) -> ReversedDisplay<'_, Self>
fn reversed(&self) -> ReversedDisplay<'_, Self>
Source§fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
Source§fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::fg or
a color-specific method, such as OwoColorize::green, Read moreSource§fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::bg or
a color-specific method, such as OwoColorize::on_yellow, Read more