pub struct FileSystemStorage { /* private fields */ }Expand description
Filesystem-backed cache storage rooted at a directory.
Persists cached responses under a root directory so they survive process restarts. Each
response is two files: a <hash>.meta sidecar holding the CachePolicy and any trailers
as an rkyv-encoded binary blob, and a <hash>.body holding the raw body bytes and nothing
else. Bodies stream in and out — put writes to a temporary file the caller feeds
incrementally, and open streams the stored body back without loading it into memory. The
metadata is not human-readable; it is optimized for compact, fast loading rather than
inspection.
Defaults to a 1 GiB byte cap; override with
with_max_capacity_bytes or remove it with
unbounded.
Clone is cheap — clones share the same root and capacity index, and see each other’s
writes.
§Layout
Entries live at <root>/<key-hash>/<variant-hash>.{meta,body}. The key hash is a SHA-256
of the request method and URL; the variant hash is a SHA-256 of the Vary signature, so
the multiple variants of one URL are sibling files in the same directory and get
enumerates them by reading that directory. Writing a variant that already exists replaces
it.
§Durability
Writes commit by renaming a fully-written temporary file into place, and the .meta is
written last — a reader treats it as the commit marker, so a half-written or abandoned entry
(a PutHandle dropped without finalize) is never visible to get.
§Capacity
A byte cap (1 GiB by default) bounds the total stored body size. When a write would push
the total past the cap, least-recently-used variants are evicted — their .meta and
.body files deleted — until the cache fits. The cap counts body bytes only, per variant,
matching the granularity of the on-disk layout. Reads count as use, so a frequently-served
variant outlives idle ones. Override with with_max_capacity_bytes or remove the cap with
unbounded.
The cap is tracked in an in-memory index built by scanning the root at construction, so it survives restarts (recency resets to whatever order the scan encounters). A directory that grew past the current cap under an older, unbounded configuration is trimmed to fit on the next construction.
§Runtime
Filesystem access goes through the runtime selected by the smol, tokio, or async-std
feature. Enabling fs without one of those compiles but panics on use.
Implementations§
Source§impl FileSystemStorage
impl FileSystemStorage
Sourcepub fn new(root: impl Into<PathBuf>) -> Self
pub fn new(root: impl Into<PathBuf>) -> Self
Construct a storage rooted at root with a 1 GiB byte cap. The directory is created
on demand as entries are written; it need not exist yet. If it exists, it is scanned
to seed the capacity index, so previously stored entries count against the cap.
Sourcepub fn with_max_capacity_bytes(self, bytes: u64) -> Self
pub fn with_max_capacity_bytes(self, bytes: u64) -> Self
Set the maximum total stored body size, in bytes. Least-recently-used variants are evicted — their files deleted — when a write would exceed this cap. Defaults to 1 GiB. Re-scans the root, so a directory already over the new cap is trimmed to fit.
Sourcepub fn unbounded(self) -> Self
pub fn unbounded(self) -> Self
Remove the size cap. Stored bytes grow without bound. Useful in tests and short-lived processes; a cache living on shared disk should prefer the default capped configuration.
Sourcepub fn weighted_size(&self) -> u64
pub fn weighted_size(&self) -> u64
Approximate total stored body size, in bytes, currently counted against the cap.
Eventually consistent — call run_pending_tasks first for
a settled value.
Sourcepub fn entry_count(&self) -> u64
pub fn entry_count(&self) -> u64
Approximate count of stored variants. Eventually consistent — call
run_pending_tasks first for a settled value.
Sourcepub async fn run_pending_tasks(&self)
pub async fn run_pending_tasks(&self)
Flush pending eviction bookkeeping, including deletion of files for evicted variants.
Call before reading weighted_size or
entry_count when an exact value matters.
Trait Implementations§
Source§impl CacheStorage for FileSystemStorage
impl CacheStorage for FileSystemStorage
Source§type PutHandle = FsPutHandle
type PutHandle = FsPutHandle
put.Source§type StoredEntry = FsStoredEntry
type StoredEntry = FsStoredEntry
get.Source§async fn get(&self, key: &CacheKey) -> Vec<Self::StoredEntry>
async fn get(&self, key: &CacheKey) -> Vec<Self::StoredEntry>
key. Returns an empty vec when
the key has no entries.Source§async fn put(
&self,
key: CacheKey,
policy: CachePolicy,
) -> Result<Self::PutHandle>
async fn put( &self, key: CacheKey, policy: CachePolicy, ) -> Result<Self::PutHandle>
key with the supplied policy.
Returns a PutHandle that the caller writes body bytes into,
then closes with PutHandle::finalize. If an existing entry
has the same Vary signature, finalize replaces it; otherwise
the new entry is appended. Read moreSource§async fn invalidate(&self, key: &CacheKey)
async fn invalidate(&self, key: &CacheKey)
key.Source§impl Clone for FileSystemStorage
impl Clone for FileSystemStorage
Source§fn clone(&self) -> FileSystemStorage
fn clone(&self) -> FileSystemStorage
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl !RefUnwindSafe for FileSystemStorage
impl !UnwindSafe for FileSystemStorage
impl Freeze for FileSystemStorage
impl Send for FileSystemStorage
impl Sync for FileSystemStorage
impl Unpin for FileSystemStorage
impl UnsafeUnpin for FileSystemStorage
Blanket Implementations§
Source§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
Source§type ArchivedMetadata = ()
type ArchivedMetadata = ()
Source§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
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> LayoutRaw for T
impl<T> LayoutRaw for T
Source§fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
Source§impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
Source§unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
Source§fn resolve_niched(out: Place<NichedOption<T, N1>>)
fn resolve_niched(out: Place<NichedOption<T, N1>>)
out indicating that a T is niched.