mocra_core/common/processors/
processor.rs1#![allow(unused)]
2
3use crate::errors::error::{Error, Result};
4use async_trait::async_trait;
5use std::collections::HashMap;
6use std::sync::Arc;
7use tokio::sync::RwLock;
8
9#[derive(Debug, Clone)]
11pub struct RetryPolicy {
12 pub max_retries: u32,
14 pub retry_delay: u64,
16 pub current_retry: u32,
18 pub reason: Option<String>,
20 pub meta: serde_json::Value,
22}
23impl Default for RetryPolicy {
24 fn default() -> Self {
25 Self {
26 max_retries: 3,
27 retry_delay: 2000,
28 current_retry: 0,
29 reason: None,
30 meta: Default::default(),
31 }
32 }
33}
34
35impl RetryPolicy {
36 pub fn should_retry(&self) -> bool {
38 self.current_retry < self.max_retries
39 }
40 pub fn next_retry_delay(&self) -> u64 {
42 self.retry_delay * (self.current_retry + 1) as u64
43 }
44 pub fn increment_retry(&mut self) {
46 self.current_retry += 1;
47 }
48 pub fn reset(&mut self) {
50 self.current_retry = 0;
51 self.retry_delay = 2000;
52 }
53 pub async fn delay_next_retry(&mut self) -> Option<u64> {
55 if !self.should_retry() {
56 return None;
57 }
58 self.increment_retry();
59 let delay = self.next_retry_delay();
60 Some(delay)
61 }
62
63 pub fn with_meta(mut self, key: &str, value: serde_json::Value) -> Self {
65 if let serde_json::Value::Object(ref mut map) = self.meta {
66 map.insert(key.to_string(), value);
67 }
68 self
69 }
70 pub fn with_reason(mut self, reason: String) -> Self {
72 self.reason = Some(reason);
73 self
74 }
75 pub fn with_delay(mut self, delay_ms: u64) -> Self {
77 self.retry_delay = delay_ms;
78 self
79 }
80}
81
82#[derive(Debug)]
84pub enum ProcessorResult<T> {
85 Success(T),
87 RetryableFailure(RetryPolicy),
89 FatalFailure(Error),
91}
92
93impl<T> ProcessorResult<T> {
94 pub fn is_success(&self) -> bool {
95 matches!(self, ProcessorResult::Success(_))
96 }
97
98 pub fn is_failure(&self) -> bool {
99 matches!(
100 self,
101 ProcessorResult::RetryableFailure(_) | ProcessorResult::FatalFailure(_)
102 )
103 }
104
105 pub fn is_retryable(&self) -> bool {
106 matches!(self, ProcessorResult::RetryableFailure(_))
107 }
108}
109
110#[derive(Debug, Clone)]
112pub struct ProcessorContext {
113 pub metadata: Arc<RwLock<HashMap<String, serde_json::Value>>>,
115 pub retry_policy: Option<RetryPolicy>,
117 pub created_at: u64,
119 pub step_timeout_ms: Option<u64>,
121 pub cancelled: bool,
123}
124
125impl Default for ProcessorContext {
126 fn default() -> Self {
127 Self {
128 metadata: Default::default(),
129 retry_policy: None,
130 created_at: std::time::SystemTime::now()
131 .duration_since(std::time::UNIX_EPOCH)
132 .unwrap()
133 .as_secs(),
134 step_timeout_ms: None,
135 cancelled: false,
136 }
137 }
138}
139
140impl ProcessorContext {
141 pub fn new() -> Self {
142 Self::default()
143 }
144 pub async fn with_metadata(mut self, key: String, value: serde_json::Value) -> Self {
145 self.metadata.write().await.insert(key, value);
146 self
147 }
148
149 pub fn with_retry_policy(mut self, retry_policy: RetryPolicy) -> Self {
150 self.retry_policy = Some(retry_policy);
151 self
152 }
153
154 pub fn with_step_timeout_ms(mut self, ms: u64) -> Self {
155 self.step_timeout_ms = Some(ms);
156 self
157 }
158
159 pub fn cancel(mut self) -> Self {
160 self.cancelled = true;
161 self
162 }
163}
164
165#[async_trait]
167pub trait ProcessorTrait<Input, Output>: Send + Sync {
168 fn name(&self) -> &'static str;
170
171 async fn process(&self, input: Input, context: ProcessorContext) -> ProcessorResult<Output>;
173
174 async fn pre_process(&self, _input: &Input, _context: &ProcessorContext) -> Result<()> {
176 Ok(())
177 }
178
179 async fn post_process(
181 &self,
182 _input: &Input,
183 _output: &Output,
184 _context: &ProcessorContext,
185 ) -> Result<()> {
186 Ok(())
187 }
188
189 async fn handle_error(
191 &self,
192 _input: &Input,
193 _error: Error,
194 _context: &ProcessorContext,
195 ) -> ProcessorResult<Output> {
196 ProcessorResult::FatalFailure(_error)
197 }
198
199 async fn should_process(&self, _input: &Input, _context: &ProcessorContext) -> bool {
201 true
202 }
203}
204
205#[async_trait]
207pub trait ConfigurableProcessor<Input, Output, Config>: ProcessorTrait<Input, Output> {
208 async fn apply_config(&mut self, config: Config) -> Result<()>;
210
211 fn get_config(&self) -> Option<&Config>;
213}