pub struct ResilientStorage { /* private fields */ }Expand description
Resilient storage wrapper with circuit breaker protection
Wraps TursoStorage operations with circuit breaker pattern to provide:
- Fast failure when service is down
- Automatic recovery attempts
- Failure statistics and monitoring
Implementations§
Source§impl ResilientStorage
impl ResilientStorage
Sourcepub fn new(storage: TursoStorage, config: CircuitBreakerConfig) -> Self
pub fn new(storage: TursoStorage, config: CircuitBreakerConfig) -> Self
Create a new resilient storage wrapper
§Arguments
storage- Turso storage backend to wrapconfig- Circuit breaker configuration
§Example
let turso = TursoStorage::new("libsql://localhost:8080", "token").await?;
let config = CircuitBreakerConfig {
failure_threshold: 5,
timeout: std::time::Duration::from_secs(30),
..Default::default()
};
let resilient = ResilientStorage::new(turso, config);Sourcepub async fn circuit_state(&self) -> CircuitState
pub async fn circuit_state(&self) -> CircuitState
Get the current circuit breaker state
Useful for monitoring and health checks.
§Example
let state = storage.circuit_state().await;
match state {
CircuitState::Closed => println!("Circuit is healthy"),
CircuitState::Open => println!("Circuit is open - service down"),
CircuitState::HalfOpen => println!("Circuit is testing recovery"),
}Sourcepub async fn circuit_stats(&self) -> CircuitBreakerStats
pub async fn circuit_stats(&self) -> CircuitBreakerStats
Get circuit breaker statistics
§Example
let stats = storage.circuit_stats().await;
println!("Total calls: {}", stats.total_calls);
println!("Failures: {}", stats.failed_calls);
println!("Circuit opened {} times", stats.circuit_opened_count);Sourcepub async fn reset_circuit(&self)
pub async fn reset_circuit(&self)
Reset the circuit breaker
Useful for manual intervention or testing.
Sourcepub async fn health_check(&self) -> Result<bool>
pub async fn health_check(&self) -> Result<bool>
Health check with circuit breaker awareness
Returns true if both the storage is healthy AND the circuit is closed.
Trait Implementations§
Source§impl StorageBackend for ResilientStorage
impl StorageBackend for ResilientStorage
Source§fn store_episode<'life0, 'life1, 'async_trait>(
&'life0 self,
episode: &'life1 Episode,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn store_episode<'life0, 'life1, 'async_trait>(
&'life0 self,
episode: &'life1 Episode,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Store an episode Read more
Source§fn get_episode<'life0, 'async_trait>(
&'life0 self,
id: Uuid,
) -> Pin<Box<dyn Future<Output = Result<Option<Episode>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_episode<'life0, 'async_trait>(
&'life0 self,
id: Uuid,
) -> Pin<Box<dyn Future<Output = Result<Option<Episode>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Retrieve an episode by ID Read more
Source§fn delete_episode<'life0, 'async_trait>(
&'life0 self,
id: Uuid,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn delete_episode<'life0, 'async_trait>(
&'life0 self,
id: Uuid,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Delete an episode by ID Read more
Source§fn store_pattern<'life0, 'life1, 'async_trait>(
&'life0 self,
pattern: &'life1 Pattern,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn store_pattern<'life0, 'life1, 'async_trait>(
&'life0 self,
pattern: &'life1 Pattern,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Store a pattern Read more
Source§fn get_pattern<'life0, 'async_trait>(
&'life0 self,
id: PatternId,
) -> Pin<Box<dyn Future<Output = Result<Option<Pattern>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_pattern<'life0, 'async_trait>(
&'life0 self,
id: PatternId,
) -> Pin<Box<dyn Future<Output = Result<Option<Pattern>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Retrieve a pattern by ID Read more
Source§fn store_heuristic<'life0, 'life1, 'async_trait>(
&'life0 self,
heuristic: &'life1 Heuristic,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn store_heuristic<'life0, 'life1, 'async_trait>(
&'life0 self,
heuristic: &'life1 Heuristic,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Store a heuristic Read more
Source§fn get_heuristic<'life0, 'async_trait>(
&'life0 self,
id: Uuid,
) -> Pin<Box<dyn Future<Output = Result<Option<Heuristic>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_heuristic<'life0, 'async_trait>(
&'life0 self,
id: Uuid,
) -> Pin<Box<dyn Future<Output = Result<Option<Heuristic>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Retrieve a heuristic by ID Read more
Source§fn query_episodes_since<'life0, 'async_trait>(
&'life0 self,
since: DateTime<Utc>,
limit: Option<usize>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Episode>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn query_episodes_since<'life0, 'async_trait>(
&'life0 self,
since: DateTime<Utc>,
limit: Option<usize>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Episode>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Query episodes modified since a given timestamp Read more
Source§fn query_episodes_by_metadata<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
key: &'life1 str,
value: &'life2 str,
limit: Option<usize>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Episode>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn query_episodes_by_metadata<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
key: &'life1 str,
value: &'life2 str,
limit: Option<usize>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Episode>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Query episodes by metadata key-value pair Read more
Source§fn store_embedding<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
embedding: Vec<f32>,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn store_embedding<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
embedding: Vec<f32>,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Store embedding for an episode or pattern Read more
Source§fn get_embedding<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<Vec<f32>>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_embedding<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<Vec<f32>>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Retrieve embedding by ID Read more
Source§fn delete_embedding<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn delete_embedding<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<bool>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Delete embedding by ID Read more
Source§fn store_embeddings_batch<'life0, 'async_trait>(
&'life0 self,
embeddings: Vec<(String, Vec<f32>)>,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn store_embeddings_batch<'life0, 'async_trait>(
&'life0 self,
embeddings: Vec<(String, Vec<f32>)>,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Store multiple embeddings in batch Read more
Source§fn get_embeddings_batch<'life0, 'life1, 'async_trait>(
&'life0 self,
ids: &'life1 [String],
) -> Pin<Box<dyn Future<Output = Result<Vec<Option<Vec<f32>>>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_embeddings_batch<'life0, 'life1, 'async_trait>(
&'life0 self,
ids: &'life1 [String],
) -> Pin<Box<dyn Future<Output = Result<Vec<Option<Vec<f32>>>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Get embeddings for multiple IDs Read more
Source§fn store_recommendation_session<'life0, 'life1, 'async_trait>(
&'life0 self,
session: &'life1 RecommendationSession,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn store_recommendation_session<'life0, 'life1, 'async_trait>(
&'life0 self,
session: &'life1 RecommendationSession,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Persist a recommendation session for durability and analytics.
Source§fn get_recommendation_session<'life0, 'async_trait>(
&'life0 self,
session_id: Uuid,
) -> Pin<Box<dyn Future<Output = Result<Option<RecommendationSession>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_recommendation_session<'life0, 'async_trait>(
&'life0 self,
session_id: Uuid,
) -> Pin<Box<dyn Future<Output = Result<Option<RecommendationSession>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Retrieve a recommendation session by ID.
Source§fn get_recommendation_session_for_episode<'life0, 'async_trait>(
&'life0 self,
episode_id: Uuid,
) -> Pin<Box<dyn Future<Output = Result<Option<RecommendationSession>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_recommendation_session_for_episode<'life0, 'async_trait>(
&'life0 self,
episode_id: Uuid,
) -> Pin<Box<dyn Future<Output = Result<Option<RecommendationSession>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Retrieve the most recent recommendation session for an episode.
Source§fn store_recommendation_feedback<'life0, 'life1, 'async_trait>(
&'life0 self,
feedback: &'life1 RecommendationFeedback,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn store_recommendation_feedback<'life0, 'life1, 'async_trait>(
&'life0 self,
feedback: &'life1 RecommendationFeedback,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Persist feedback associated with a recommendation session.
Source§fn get_recommendation_feedback<'life0, 'async_trait>(
&'life0 self,
session_id: Uuid,
) -> Pin<Box<dyn Future<Output = Result<Option<RecommendationFeedback>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_recommendation_feedback<'life0, 'async_trait>(
&'life0 self,
session_id: Uuid,
) -> Pin<Box<dyn Future<Output = Result<Option<RecommendationFeedback>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Retrieve feedback for a recommendation session.
Source§fn get_recommendation_stats<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<RecommendationStats>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn get_recommendation_stats<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<RecommendationStats>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Compute global recommendation statistics.
Source§fn store_relationship<'life0, 'life1, 'async_trait>(
&'life0 self,
relationship: &'life1 EpisodeRelationship,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn store_relationship<'life0, 'life1, 'async_trait>(
&'life0 self,
relationship: &'life1 EpisodeRelationship,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Store a relationship between two episodes Read more
Source§fn remove_relationship<'life0, 'async_trait>(
&'life0 self,
relationship_id: Uuid,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn remove_relationship<'life0, 'async_trait>(
&'life0 self,
relationship_id: Uuid,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Remove a relationship by ID Read more
Source§fn get_relationships<'life0, 'async_trait>(
&'life0 self,
episode_id: Uuid,
direction: Direction,
) -> Pin<Box<dyn Future<Output = Result<Vec<EpisodeRelationship>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn get_relationships<'life0, 'async_trait>(
&'life0 self,
episode_id: Uuid,
direction: Direction,
) -> Pin<Box<dyn Future<Output = Result<Vec<EpisodeRelationship>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Get relationships for an episode Read more
Source§fn relationship_exists<'life0, 'async_trait>(
&'life0 self,
from_episode_id: Uuid,
to_episode_id: Uuid,
relationship_type: RelationshipType,
) -> Pin<Box<dyn Future<Output = Result<bool, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn relationship_exists<'life0, 'async_trait>(
&'life0 self,
from_episode_id: Uuid,
to_episode_id: Uuid,
relationship_type: RelationshipType,
) -> Pin<Box<dyn Future<Output = Result<bool, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Check if a relationship exists Read more
Source§fn cleanup_episodes<'life0, 'life1, 'async_trait>(
&'life0 self,
policy: &'life1 EpisodeRetentionPolicy,
) -> Pin<Box<dyn Future<Output = Result<CleanupResult, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn cleanup_episodes<'life0, 'life1, 'async_trait>(
&'life0 self,
policy: &'life1 EpisodeRetentionPolicy,
) -> Pin<Box<dyn Future<Output = Result<CleanupResult, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Clean up expired episodes based on retention policy Read more
Source§fn count_cleanup_candidates<'life0, 'life1, 'async_trait>(
&'life0 self,
policy: &'life1 EpisodeRetentionPolicy,
) -> Pin<Box<dyn Future<Output = Result<usize, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn count_cleanup_candidates<'life0, 'life1, 'async_trait>(
&'life0 self,
policy: &'life1 EpisodeRetentionPolicy,
) -> Pin<Box<dyn Future<Output = Result<usize, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Get count of episodes that would be cleaned up (dry run) Read more
Auto Trait Implementations§
impl Freeze for ResilientStorage
impl !RefUnwindSafe for ResilientStorage
impl Send for ResilientStorage
impl Sync for ResilientStorage
impl Unpin for ResilientStorage
impl UnsafeUnpin for ResilientStorage
impl !UnwindSafe for ResilientStorage
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
Mutably borrows from an owned value. Read more
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> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
Wrap the input message
T in a tonic::RequestSource§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
The inverse inclusion map: attempts to construct
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
Checks if
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
Use with care! Same as
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
The inclusion map: converts
self to the equivalent element of its superset.Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
The inverse inclusion map: attempts to construct
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
Checks if
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
Use with care! Same as
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
The inclusion map: converts
self to the equivalent element of its superset.