pub struct S3Store { /* private fields */ }Implementations§
Source§impl S3Store
impl S3Store
Sourcepub fn new(client: Client, bucket: impl Into<String>) -> Self
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.
Sourcepub fn with_ancestor_cap(self, cap: usize) -> Result<Self>
pub fn with_ancestor_cap(self, cap: usize) -> Result<Self>
Override the ancestor cap (spec §3.9). A cap of 0 is rejected.
Sourcepub async fn connect(
bucket: impl Into<String>,
endpoint: Option<String>,
region: Option<String>,
) -> Self
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).
Sourcepub async fn collection_marked(
&self,
namespace: &str,
collection: &str,
) -> Result<bool>
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.
Sourcepub async fn mark_collection(
&self,
namespace: &str,
collection: &str,
) -> Result<()>
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.
Sourcepub async fn marker_exists(&self, key: &RecordKey) -> Result<bool>
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
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,
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,
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,
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,
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,
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,
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,
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,
hash. Deleting an absent blob is an
idempotent no-op — GC may race another sweeper or a re-put.Source§impl Store for S3Store
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,
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,
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,
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,
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,
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,
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 moreSource§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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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§
impl !RefUnwindSafe for S3Store
impl !UnwindSafe for S3Store
impl Freeze for S3Store
impl Send for S3Store
impl Sync for S3Store
impl Unpin for S3Store
impl UnsafeUnpin for S3Store
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
impl<T> ErasedDestructor for Twhere
T: 'static,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> 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 more