use std::error::Error;
use std::fmt;
use std::sync::Arc;
use super::identity::validate_identifier;
use super::{IdentityError, IdentityKind};
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct CacheOwnerId(Arc<str>);
impl CacheOwnerId {
pub fn new(value: impl Into<Arc<str>>) -> Result<Self, IdentityError> {
validate_identifier(value.into(), IdentityKind::CacheOwner).map(Self)
}
pub fn as_str(&self) -> &str {
&self.0
}
pub(super) fn from_canonical_owner_id(value: Arc<str>) -> Self {
Self(value)
}
}
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub struct CacheStats {
pub entries: usize,
pub retained_bytes: usize,
pub hits: u64,
pub misses: u64,
pub evictions: u64,
pub clears: u64,
}
pub trait RuntimeCacheOwner: fmt::Debug + Send + Sync + 'static {
fn cache_stats(&self) -> Result<CacheStats, CacheOwnerError>;
fn clear_caches(&self) -> Result<(), CacheOwnerError>;
}
#[derive(Clone)]
pub struct CacheOwnerError {
source: Arc<dyn Error + Send + Sync>,
}
impl CacheOwnerError {
pub fn new(source: Arc<dyn Error + Send + Sync>) -> Self {
Self { source }
}
pub fn source_arc(&self) -> &Arc<dyn Error + Send + Sync> {
&self.source
}
}
impl fmt::Debug for CacheOwnerError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter
.debug_struct("CacheOwnerError")
.field("source", &self.source.to_string())
.finish()
}
}
impl fmt::Display for CacheOwnerError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "{}", self.source)
}
}
impl Error for CacheOwnerError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
Some(self.source.as_ref())
}
}
#[derive(Clone, Debug)]
pub struct CacheOwnerFailure {
pub owner: CacheOwnerId,
pub source: CacheOwnerError,
}
#[derive(Clone, Copy, Debug)]
pub(super) enum FrozenCacheOwnerKind {
Extension,
}
#[derive(Clone)]
pub(super) struct FrozenCacheOwner {
pub(super) id: CacheOwnerId,
pub(super) kind: FrozenCacheOwnerKind,
pub(super) owner: Arc<dyn RuntimeCacheOwner>,
}
impl fmt::Debug for FrozenCacheOwner {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter
.debug_struct("FrozenCacheOwner")
.field("id", &self.id)
.field("kind", &self.kind)
.field("owner_strong_count", &Arc::strong_count(&self.owner))
.finish()
}
}
#[derive(Debug, thiserror::Error)]
pub enum RuntimeStateError {
#[error("{lock} poisoned")]
Poisoned {
lock: &'static str,
},
}
#[derive(Debug, thiserror::Error)]
pub enum RuntimeCacheError {
#[error("runtime cache operation failed")]
Aggregate {
runtime: Option<RuntimeStateError>,
owners: Box<[CacheOwnerFailure]>,
},
}