pub struct PgStorageBackend<C>where
C: PgCacheConn,{ /* private fields */ }Expand description
L2 durable cache tier: content-addressed key → value over Postgres, shared across pods, survives a roll.
Generic over the PgCacheConn seam so it is fully testable against a mock.
Implementations§
Source§impl<C> PgStorageBackend<C>where
C: PgCacheConn,
impl<C> PgStorageBackend<C>where
C: PgCacheConn,
Sourcepub fn new(conn: C) -> PgStorageBackend<C>
pub fn new(conn: C) -> PgStorageBackend<C>
Wrap a PgCacheConn.
Trait Implementations§
Source§impl<C> NarRefIndex for PgStorageBackend<C>where
C: PgCacheConn + 'static,
The reverse index as one zero-value row per edge in sui_cache_nar_ref.
impl<C> NarRefIndex for PgStorageBackend<C>where
C: PgCacheConn + 'static,
The reverse index as one zero-value row per edge in sui_cache_nar_ref.
The key is the canonical NarRefKey, so the referrer lookup is a
primary-key range scan under NarRefScan rather than a table sweep.
Source§fn record<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
nar_path: &'life1 str,
hash: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
PgStorageBackend<C>: 'async_trait,
fn record<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
nar_path: &'life1 str,
hash: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
PgStorageBackend<C>: 'async_trait,
Source§fn forget<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
nar_path: &'life1 str,
hash: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
PgStorageBackend<C>: 'async_trait,
fn forget<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
nar_path: &'life1 str,
hash: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
PgStorageBackend<C>: 'async_trait,
Ok(()). Read moreSource§fn referrers<'life0, 'life1, 'async_trait>(
&'life0 self,
nar_path: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<String>, StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
PgStorageBackend<C>: 'async_trait,
fn referrers<'life0, 'life1, 'async_trait>(
&'life0 self,
nar_path: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Vec<String>, StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
PgStorageBackend<C>: 'async_trait,
nar_path, sorted and
deduplicated. Read moreSource§impl<C> StorageBackend for PgStorageBackend<C>where
C: PgCacheConn + 'static,
impl<C> StorageBackend for PgStorageBackend<C>where
C: PgCacheConn + 'static,
Source§fn delete_nar_record<'life0, 'life1, 'async_trait>(
&'life0 self,
nar_path: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
PgStorageBackend<C>: 'async_trait,
fn delete_nar_record<'life0, 'life1, 'async_trait>(
&'life0 self,
nar_path: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
PgStorageBackend<C>: 'async_trait,
Remove a NAR by key, clearing both generations.
A key may exist as a legacy whole-value row (written before the streaming path) or as chunk rows, and a NAR that was re-pushed across the change can be both. Dropping only one leaves the other still readable, so a “deleted” NAR would keep serving.
Source§fn nar_residency(&self) -> NarResidency
fn nar_residency(&self) -> NarResidency
O(chunk). A NAR crosses the wire as NAR_CHUNK_BYTES rows in both
directions; no statement ever binds or returns the whole value.
Source§fn get_nar_stream<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<Pin<Box<dyn Stream<Item = Result<Bytes, StoreError>> + Send>>>, StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
PgStorageBackend<C>: 'async_trait,
fn get_nar_stream<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<Pin<Box<dyn Stream<Item = Result<Bytes, StoreError>> + Send>>>, StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
PgStorageBackend<C>: 'async_trait,
Read a NAR back as bounded chunks, from either storage generation.
Chunked rows are checked first (via the marker); a key with no marker
falls back to windowing a legacy whole-value row with substr. Both
arms are O(chunk) — the fallback exists so the NARs already in the
production database are servable without materializing them, not as a
buffered escape hatch.
Source§fn put_nar_stream<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
path: &'life1 str,
src: &'life2 dyn NarSource,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
PgStorageBackend<C>: 'async_trait,
fn put_nar_stream<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
path: &'life1 str,
src: &'life2 dyn NarSource,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
PgStorageBackend<C>: 'async_trait,
Write a NAR as bounded chunk rows, publishing with a marker written last.
Order is the invariant, not a convention:
- drop any prior chunks and the legacy whole row — a stale marker or a stale legacy row would otherwise shadow the new value;
- write chunks
0..n, each a bounded bind; - write the marker.
A failure anywhere in (1)–(2) leaves no marker, so the key reads as a clean miss. There is no window in which a reader can observe a truncated NAR.
Source§fn wipe_all<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<usize, StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
PgStorageBackend<C>: 'async_trait,
fn wipe_all<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<usize, StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
PgStorageBackend<C>: 'async_trait,
Complete L2 wipe: truncate the narinfo, legacy NAR, NAR-chunk and
reverse-edge tables. Unlike the per-hash delete, this reclaims NAR rows
wholesale. Returns the narinfo row count.
Source§fn get_narinfo<'life0, 'life1, 'async_trait>(
&'life0 self,
hash: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<String>, StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
PgStorageBackend<C>: 'async_trait,
fn get_narinfo<'life0, 'life1, 'async_trait>(
&'life0 self,
hash: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<String>, StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
PgStorageBackend<C>: 'async_trait,
Source§fn put_narinfo_record<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
hash: &'life1 str,
content: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
PgStorageBackend<C>: 'async_trait,
fn put_narinfo_record<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
hash: &'life1 str,
content: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
PgStorageBackend<C>: 'async_trait,
Source§fn delete_narinfo_record<'life0, 'life1, 'async_trait>(
&'life0 self,
hash: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
PgStorageBackend<C>: 'async_trait,
fn delete_narinfo_record<'life0, 'life1, 'async_trait>(
&'life0 self,
hash: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
PgStorageBackend<C>: 'async_trait,
Ok(()). Read moreSource§fn nar_ref_index(&self) -> &dyn NarRefIndex
fn nar_ref_index(&self) -> &dyn NarRefIndex
Source§fn get_nar<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<Vec<u8>>, StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
PgStorageBackend<C>: 'async_trait,
fn get_nar<'life0, 'life1, 'async_trait>(
&'life0 self,
path: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<Vec<u8>>, StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
PgStorageBackend<C>: 'async_trait,
Source§fn put_nar<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
path: &'life1 str,
data: &'life2 [u8],
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
PgStorageBackend<C>: 'async_trait,
fn put_nar<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
path: &'life1 str,
data: &'life2 [u8],
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
PgStorageBackend<C>: 'async_trait,
Source§fn list_narinfos<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<String>, StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
PgStorageBackend<C>: 'async_trait,
fn list_narinfos<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Vec<String>, StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
PgStorageBackend<C>: 'async_trait,
Source§fn put_narinfo<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
hash: &'life1 str,
content: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn put_narinfo<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
hash: &'life1 str,
content: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
Source§fn advertised_nar<'life0, 'life1, 'async_trait>(
&'life0 self,
hash: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<String>, StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn advertised_nar<'life0, 'life1, 'async_trait>(
&'life0 self,
hash: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<String>, StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Source§fn delete<'life0, 'life1, 'async_trait>(
&'life0 self,
hash: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn delete<'life0, 'life1, 'async_trait>(
&'life0 self,
hash: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<(), StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Source§fn reindex_nar_refs<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<usize, StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn reindex_nar_refs<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<usize, StoreError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Auto Trait Implementations§
impl<C> Freeze for PgStorageBackend<C>
impl<C> RefUnwindSafe for PgStorageBackend<C>where
C: RefUnwindSafe,
impl<C> Send for PgStorageBackend<C>
impl<C> Sync for PgStorageBackend<C>
impl<C> Unpin for PgStorageBackend<C>
impl<C> UnsafeUnpin for PgStorageBackend<C>
impl<C> UnwindSafe for PgStorageBackend<C>where
C: RefUnwindSafe,
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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
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> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
Source§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();Source§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
Source§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
Source§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
Source§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
Source§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
Source§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
Source§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
Source§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
Source§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();Source§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
Source§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
Source§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
Source§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
Source§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
Source§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
Source§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
Source§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
Source§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
Source§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
Source§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling Attribute value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();Source§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
Source§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi Quirk value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();Source§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
Source§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the Condition value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);