Skip to main content

S3Store

Struct S3Store 

Source
pub struct S3Store { /* private fields */ }

Implementations§

Source§

impl S3Store

Source

pub fn new(client: Client, bucket: impl Into<String>) -> Self

Build a store from an explicit client and bucket. Use S3Store::connect for the common env/endpoint path.

Source

pub fn with_ancestor_cap(self, cap: usize) -> Result<Self>

Override the ancestor cap (spec §3.9). A cap of 0 is rejected.

Source

pub async fn connect( bucket: impl Into<String>, endpoint: Option<String>, region: Option<String>, ) -> Self

Connect using the ambient AWS config (env, profile, IRSA, etc.). If endpoint is Some, target an S3-compatible server (MinIO/Garage, etc.) with path-style addressing; if region is Some, override the ambient region (else the AWS env/profile region applies).

Source

pub async fn collection_marked( &self, namespace: &str, collection: &str, ) -> Result<bool>

Whether list may treat an unmarked key in this collection as live — true once the collection carries the marked flag (ADR 0025).

A bucket written before markers existed has tombstones with no marker, and trusting their absence there would resurrect deleted records. So trust is earned per collection, by a pass that read every key and backfilled what was missing.

Source

pub async fn mark_collection( &self, namespace: &str, collection: &str, ) -> Result<()>

Record that every tombstone in this collection carries a marker.

Only for a caller that just read every key in the collection and wrote the markers that were missing — the flag is what later listings trust instead of reading.

Source

pub async fn marker_exists(&self, key: &RecordKey) -> Result<bool>

Whether key currently carries a tombstone marker.

For inspecting the layout — tests and operational debugging. list reads markers out of the listing it already made instead, which is the entire point of putting them in the key space (ADR 0025).

Trait Implementations§

Source§

impl BlobStore for S3Store

Source§

fn put_blob<'life0, 'life1, 'async_trait>( &'life0 self, content: &'life1 [u8], ) -> Pin<Box<dyn Future<Output = Result<ContentHash>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Store content addressed by its hash, write-if-absent, and return the hash. Idempotent: storing identical content again is a no-op.
Source§

fn get_blob<'life0, 'life1, 'async_trait>( &'life0 self, hash: &'life1 ContentHash, ) -> Pin<Box<dyn Future<Output = Result<Option<Vec<u8>>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Fetch blob content by hash, or None if absent.
Source§

fn list_blobs<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<BlobEntry>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Every stored blob with the time it was last written. Order is unspecified, and a hash may repeat — a caller that cares resolves a duplicate to its newest timestamp. Used by GC to enumerate candidates and decide which are old enough to sweep (ADR 0024, 0028).
Source§

fn delete_blob<'life0, 'life1, 'async_trait>( &'life0 self, hash: &'life1 ContentHash, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Delete the blob addressed by hash. Deleting an absent blob is an idempotent no-op — GC may race another sweeper or a re-put.
Source§

fn has_blob<'life0, 'life1, 'async_trait>( &'life0 self, hash: &'life1 ContentHash, ) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Whether hash is stored. Read more
Source§

impl Store for S3Store

Source§

fn get<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 RecordKey, ) -> Pin<Box<dyn Future<Output = Result<Option<Record>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Fetch a record by key. Returns None for an absent key and for a tombstoned one: a delete is invisible on this surface, and only get_raw shows the tombstone. See ADR 0021.
Source§

fn list<'life0, 'life1, 'async_trait>( &'life0 self, prefix: &'life1 KeyPrefix, ) -> Pin<Box<dyn Future<Output = Result<Vec<RecordKey>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

List keys matching prefix, excluding tombstoned keys. See list_raw for a listing that includes them.
Source§

fn put<'life0, 'async_trait>( &'life0 self, record: Record, expected: Option<Revision>, ) -> Pin<Box<dyn Future<Output = Result<PutResult>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Conditionally write record. expected is the revision the caller believes is current (None means “expect no existing record”). If the store’s current revision differs, returns PutResult::Conflict. Read more
Source§

fn delete_as<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 RecordKey, expected: Option<Revision>, author: Option<Identity>, ) -> Pin<Box<dyn Future<Output = Result<DeleteResult>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Conditionally delete the record at key. expected is the revision the caller believes is current: None deletes unconditionally; Some(rev) deletes only if the current revision matches, else DeleteResult::Conflict. Deleting an absent key is a no-op Deleted. Some(author) records who deleted (stores that write tombstones stamp it on the tombstone’s meta.author). See ADR 0018 and ADR 0021.
Source§

fn get_raw<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 RecordKey, ) -> Pin<Box<dyn Future<Output = Result<Option<Record>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Like get, but also returns tombstones. For replication (sync, pull, collection) only: consumers must use get. A store must never implement this by calling get, which would hide the deletions replication exists to carry. See ADR 0021.
Source§

fn list_raw<'life0, 'life1, 'async_trait>( &'life0 self, prefix: &'life1 KeyPrefix, ) -> Pin<Box<dyn Future<Output = Result<Vec<RecordKey>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Like list, but also includes tombstoned keys. For replication only. See ADR 0021.
Source§

fn put_raw<'life0, 'async_trait>( &'life0 self, record: Record, expected: Option<Revision>, ) -> Pin<Box<dyn Future<Output = Result<PutResult>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Replication write: store record exactly as given, never re-stamping. A create (expected == None) that finds anything stored, tombstones included, is a Conflict carrying it. Sync and pull use this; consumers must use put. A store must never implement this by calling put, whose recreation rule would resurrect records mid-sync. See ADR 0021.
Source§

fn purge<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 RecordKey, expected: Revision, ) -> Pin<Box<dyn Future<Output = Result<DeleteResult>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Physically remove the record at key only if its current revision is expected; otherwise DeleteResult::Conflict. Absent is an idempotent Deleted. The only physical removal in the system: used by tombstone collection, which must pass the tombstone’s revision so a record recreated in the meantime survives. See ADR 0021.
Source§

fn delete<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 RecordKey, expected: Option<Revision>, ) -> Pin<Box<dyn Future<Output = Result<DeleteResult, CoreError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait,

delete_as without an author. Provided; stores implement delete_as.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts 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 more
§

impl<Unshared, Shared> IntoShared<Shared> for Unshared
where Shared: FromUnshared<Unshared>,

§

fn into_shared(self) -> Shared

Creates a shared type from an unshared type.
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more