wesichain_core/
fallbacks.rs1use std::sync::Arc;
2
3use crate::{Runnable, StreamEvent, WesichainError};
4use async_trait::async_trait;
5use futures::stream::BoxStream;
6
7pub struct RunnableWithFallbacks<Input, Output> {
8 primary: Arc<dyn Runnable<Input, Output> + Send + Sync>,
9 fallbacks: Vec<Arc<dyn Runnable<Input, Output> + Send + Sync>>,
10}
11
12impl<Input, Output> RunnableWithFallbacks<Input, Output> {
13 pub fn new(
14 primary: Arc<dyn Runnable<Input, Output> + Send + Sync>,
15 fallbacks: Vec<Arc<dyn Runnable<Input, Output> + Send + Sync>>,
16 ) -> Self {
17 Self { primary, fallbacks }
18 }
19}
20
21#[async_trait]
22impl<Input, Output> Runnable<Input, Output> for RunnableWithFallbacks<Input, Output>
23where
24 Input: Clone + Send + Sync + 'static,
25 Output: Send + Sync + 'static,
26{
27 async fn invoke(&self, input: Input) -> Result<Output, WesichainError> {
28 let mut last_error = match self.primary.invoke(input.clone()).await {
29 Ok(output) => return Ok(output),
30 Err(e) => e,
31 };
32
33 for fallback in &self.fallbacks {
34 match fallback.invoke(input.clone()).await {
35 Ok(output) => return Ok(output),
36 Err(e) => last_error = e,
37 }
38 }
39
40 Err(last_error)
41 }
42
43 fn stream(&self, input: Input) -> BoxStream<'_, Result<StreamEvent, WesichainError>> {
44 self.primary.stream(input)
49 }
50
51 fn to_serializable(&self) -> Option<crate::serde::SerializableRunnable> {
52 let primary = Box::new(self.primary.to_serializable()?);
53 let mut fallbacks = Vec::new();
54 for f in &self.fallbacks {
55 fallbacks.push(f.to_serializable()?);
56 }
57 Some(crate::serde::SerializableRunnable::Fallbacks { primary, fallbacks })
58 }
59}