pub struct CachedDeviceStore<S>where
S: DeviceStore,{ /* private fields */ }Available on crate feature
device only.Expand description
In-process cache decorator wrapping any DeviceStore.
Construct with CachedDeviceStore::new for default settings, or
build via with_capacity /
with_ttl / with_clock.
Implementations§
Source§impl<S> CachedDeviceStore<S>where
S: DeviceStore,
impl<S> CachedDeviceStore<S>where
S: DeviceStore,
Sourcepub fn new(inner: S) -> Self
pub fn new(inner: S) -> Self
Wrap inner with default cache settings (10k entries, 60 s TTL,
SystemClock).
Sourcepub fn with_options(
inner: S,
capacity: usize,
ttl: Duration,
clock: Arc<dyn Clock>,
) -> Self
pub fn with_options( inner: S, capacity: usize, ttl: Duration, clock: Arc<dyn Clock>, ) -> Self
Construct with explicit cache parameters.
Sourcepub fn with_capacity(self, capacity: usize) -> Self
pub fn with_capacity(self, capacity: usize) -> Self
Builder: override the cache capacity (default 10,000).
Sourcepub fn with_clock(self, clock: Arc<dyn Clock>) -> Self
pub fn with_clock(self, clock: Arc<dyn Clock>) -> Self
Builder: inject a Clock for deterministic-simulation testing.
Sourcepub fn stats(&self) -> CacheStats
pub fn stats(&self) -> CacheStats
Snapshot of the underlying cache counters
(axess_cache::CacheStats). Useful for ops dashboards.
Sourcepub fn invalidate_all(&self)
pub fn invalidate_all(&self)
Drop every cached entry. Use after bulk operations that the cache wasn’t notified about (e.g. an offline migration).
Sourcepub fn invalidate_tenant(&self, tenant_id: &TenantId)
pub fn invalidate_tenant(&self, tenant_id: &TenantId)
Drop every cached entry for a given tenant. Useful after a tenant-wide trust-policy change.
Trait Implementations§
Source§impl<S> Clone for CachedDeviceStore<S>where
S: DeviceStore,
impl<S> Clone for CachedDeviceStore<S>where
S: DeviceStore,
Source§impl<S> DeviceStore for CachedDeviceStore<S>where
S: DeviceStore,
impl<S> DeviceStore for CachedDeviceStore<S>where
S: DeviceStore,
Source§type Error = <S as DeviceStore>::Error
type Error = <S as DeviceStore>::Error
The error type returned by storage operations.
Source§fn load(
&self,
tenant_id: &TenantId,
id: &DeviceId,
) -> impl Future<Output = Result<Option<Device>, Self::Error>> + Send
fn load( &self, tenant_id: &TenantId, id: &DeviceId, ) -> impl Future<Output = Result<Option<Device>, Self::Error>> + Send
Load the device by id. Returns
None if absent.Source§fn find_by_fingerprint(
&self,
tenant_id: &TenantId,
hash: &FingerprintHash,
) -> impl Future<Output = Result<Option<Device>, Self::Error>> + Send
fn find_by_fingerprint( &self, tenant_id: &TenantId, hash: &FingerprintHash, ) -> impl Future<Output = Result<Option<Device>, Self::Error>> + Send
Look up a device by its keyed fingerprint within a tenant. Used as
the fast-path during request handling when no
device_id cookie is
present yet. Collisions must be vanishingly rare given a
per-tenant HMAC key, but implementations MUST scope the query by
tenant_id to prevent cross-tenant correlation.Source§fn find_for_user(
&self,
tenant_id: &TenantId,
user_id: &UserId,
limit: usize,
) -> impl Future<Output = Result<Vec<Device>, Self::Error>> + Send
fn find_for_user( &self, tenant_id: &TenantId, user_id: &UserId, limit: usize, ) -> impl Future<Output = Result<Vec<Device>, Self::Error>> + Send
List active devices for a user, newest-sighted first.
limit caps
the result so a high-cardinality user doesn’t blow up
device-management UIs. Read moreSource§fn find_by_refresh_family(
&self,
tenant_id: &TenantId,
family_id: &str,
) -> impl Future<Output = Result<Vec<Device>, Self::Error>> + Send
fn find_by_refresh_family( &self, tenant_id: &TenantId, family_id: &str, ) -> impl Future<Output = Result<Vec<Device>, Self::Error>> + Send
Find every device in
tenant carrying a
DeviceBinding::Refresh { family_id }
matching the supplied family_id. Used by the refresh-cascade
path to convert “this refresh-token family was compromised”
into the list of Devices to revoke. Read moreSource§fn save(
&self,
device: &Device,
) -> impl Future<Output = Result<(), Self::Error>> + Send
fn save( &self, device: &Device, ) -> impl Future<Output = Result<(), Self::Error>> + Send
Persist a new device row, or overwrite an existing one. Idempotent.
Source§fn record_sighting(
&self,
tenant_id: &TenantId,
id: &DeviceId,
now: DateTime<Utc>,
) -> impl Future<Output = Result<(), Self::Error>> + Send
fn record_sighting( &self, tenant_id: &TenantId, id: &DeviceId, now: DateTime<Utc>, ) -> impl Future<Output = Result<(), Self::Error>> + Send
Touch the
last_seen_at timestamp for the given device.
Implementations SHOULD perform this as a single UPDATE rather than
a load-modify-save round trip.Source§fn set_trust_level(
&self,
tenant_id: &TenantId,
id: &DeviceId,
level: DeviceTrustLevel,
now: DateTime<Utc>,
) -> impl Future<Output = Result<(), Self::Error>> + Send
fn set_trust_level( &self, tenant_id: &TenantId, id: &DeviceId, level: DeviceTrustLevel, now: DateTime<Utc>, ) -> impl Future<Output = Result<(), Self::Error>> + Send
Set the trust level. Drives transitions across the
DeviceTrustLevel ladder. Setting to
DeviceTrustLevel::Revoked also stamps revoked_at = now.Source§fn delete(
&self,
tenant_id: &TenantId,
id: &DeviceId,
) -> impl Future<Output = Result<(), Self::Error>> + Send
fn delete( &self, tenant_id: &TenantId, id: &DeviceId, ) -> impl Future<Output = Result<(), Self::Error>> + Send
Hard-delete the row. Idempotent. Used by the retention sweep once a
Revoked device has aged out of the configured grace window, and
by Art 17 erasure cascades.Source§fn sweep(
&self,
tenant_id: &TenantId,
now: DateTime<Utc>,
) -> impl Future<Output = Result<SweepCounts, Self::Error>> + Send
fn sweep( &self, tenant_id: &TenantId, now: DateTime<Utc>, ) -> impl Future<Output = Result<SweepCounts, Self::Error>> + Send
Drive the three-stage retention ladder: Trusted → Seen (after the
configured Trusted-idle window), Seen → Revoked (after the
configured Seen-idle window), Revoked → purged (after the
configured grace window). Returns the count of rows changed at
each stage. Read more
Source§fn find_active_for_user(
&self,
tenant_id: &TenantId,
user_id: &UserId,
limit: usize,
) -> impl Future<Output = Result<Vec<Device>, Self::Error>> + Send
fn find_active_for_user( &self, tenant_id: &TenantId, user_id: &UserId, limit: usize, ) -> impl Future<Output = Result<Vec<Device>, Self::Error>> + Send
Same as
find_for_user but excludes
Revoked rows. Default implementation filters in-memory after a
full find_for_user call; SQL backends SHOULD override with a
WHERE trust_level != 'Revoked' clause that the optimiser can
use against the trust-level index.Auto Trait Implementations§
impl<S> Freeze for CachedDeviceStore<S>where
S: Freeze,
impl<S> !RefUnwindSafe for CachedDeviceStore<S>
impl<S> Send for CachedDeviceStore<S>
impl<S> Sync for CachedDeviceStore<S>
impl<S> Unpin for CachedDeviceStore<S>where
S: Unpin,
impl<S> UnsafeUnpin for CachedDeviceStore<S>where
S: UnsafeUnpin,
impl<S> !UnwindSafe for CachedDeviceStore<S>
Blanket Implementations§
Source§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
Source§type ArchivedMetadata = ()
type ArchivedMetadata = ()
The archived version of the pointer metadata for this type.
Source§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
Converts some archived metadata to the pointer metadata for itself.
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
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
Mutably borrows from an owned value. Read more
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
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>
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 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>
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 moreSource§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>
Returns the layout of the type.
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
Returns whether the given value has been niched. Read more
Source§fn resolve_niched(out: Place<NichedOption<T, N1>>)
fn resolve_niched(out: Place<NichedOption<T, N1>>)
Writes data to
out indicating that a T is niched.