Skip to content

Commit 0af7076

Browse files
committed
feat: implemented cron matching logic
1 parent 3b76c00 commit 0af7076

3 files changed

Lines changed: 53 additions & 43 deletions

File tree

adapter/cron/src/main.rs

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use std::str::FromStr;
22
use async_trait::async_trait;
3-
use chrono::{Local, Utc};
3+
use chrono::{DateTime, Datelike, Timelike, Utc};
44
use cron::Schedule;
55
use base::extract_flow_setting_field;
66
use base::runner::{ServerContext, ServerRunner};
7+
use base::store::FlowIdentifyResult;
78
use base::traits::{IdentifiableFlow, LoadConfig, Server};
89

910
#[derive(Default)]
@@ -27,15 +28,15 @@ async fn main() {
2728
}
2829

2930
struct Time {
30-
utc: Utc
31+
now: DateTime<Utc>
3132
}
3233

3334
impl IdentifiableFlow for Time {
3435
fn identify(&self, flow: &tucana::shared::ValidationFlow) -> bool {
3536
let Some(minute) = extract_flow_setting_field(&flow.settings, "CRON_MINUTE", "minute") else {
3637
return false;
3738
};
38-
let Some(hour) = extract_flow_setting_field(&flow.settings, "CRON_MOUR", "hour") else {
39+
let Some(hour) = extract_flow_setting_field(&flow.settings, "CRON_HOUR", "hour") else {
3940
return false;
4041
};
4142
let Some(dom) = extract_flow_setting_field(&flow.settings, "CRON_DAY_OF_MONTH", "day_of_month") else {
@@ -48,12 +49,15 @@ impl IdentifiableFlow for Time {
4849
return false;
4950
};
5051

51-
let expression = format!("{} {} {} {} {}", minute, hour, dom, month, dow);
52+
let expression = format!("* {} {} {} {} {}", minute, hour, dom, month, dow);
53+
let schedule = Schedule::from_str(expression.as_str()).unwrap();
54+
let next = schedule.upcoming(Utc).next().unwrap();
5255

53-
54-
55-
56-
todo!()
56+
self.now.year() == next.year() &&
57+
self.now.month() == next.month() &&
58+
self.now.day() == next.day() &&
59+
self.now.hour() == next.hour() &&
60+
self.now.minute() == next.minute()
5761
}
5862
}
5963

@@ -66,19 +70,28 @@ impl Server<CronConfig> for Cron {
6670
async fn run(&mut self, ctx: &ServerContext<CronConfig>) -> anyhow::Result<()> {
6771
let expression = "0 * * * * *";
6872
let schedule = Schedule::from_str(expression).expect("Failed to parse CRON expression");
73+
let pattern = "*.*.CRON.*";
6974

7075
loop {
7176
let now = Utc::now();
7277
if let Some(next) = schedule.upcoming(Utc).take(1).next() {
7378
let until_next = next - now;
7479
tokio::time::sleep(until_next.to_std()?).await;
75-
println!(
76-
"Running every minute. Current time: {}",
77-
Local::now().format("%Y-%m-%d %H:%M:%S")
78-
);
80+
81+
let time = Time { now };
82+
match ctx.adapter_store.get_possible_flow_match(pattern.to_string(), time).await {
83+
FlowIdentifyResult::None => {}
84+
FlowIdentifyResult::Single(flow) => {
85+
ctx.adapter_store.validate_and_execute_flow(flow, None, false).await;
86+
}
87+
FlowIdentifyResult::Multiple(flows) => {
88+
for flow in flows {
89+
ctx.adapter_store.validate_and_execute_flow(flow, None, false).await;
90+
}
91+
},
92+
}
7993
}
8094
}
81-
Ok(())
8295
}
8396

8497
async fn shutdown(&mut self, _ctx: &ServerContext<CronConfig>) -> anyhow::Result<()> {

adapter/rest/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ async fn execute_flow(
9696
request: HttpRequest,
9797
store: Arc<base::store::AdapterStore>,
9898
) -> Option<HttpResponse> {
99-
match store.validate_and_execute_flow(flow, request.body).await {
99+
match store.validate_and_execute_flow(flow, request.body, true).await {
100100
Some(result) => {
101101
let Value {
102102
kind: Some(StructValue(Struct { fields })),

crates/base/src/store.rs

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,34 @@ impl AdapterStore {
101101
}
102102
}
103103

104-
pub async fn execute(&self, flow: ExecutionFlow, wait_for_result: bool) -> Option<Value> {
104+
/// validate_and_execute_flow
105+
///
106+
/// This function will validate the flow. If the flow is valid, it will execute (send the flow to the execution and wait for a/multiple result/s) the flow.
107+
///
108+
/// Arguments:
109+
/// - flow: The flow to be validated and executed.
110+
/// - input_value: The input value to be used for the flow execution.
111+
pub async fn validate_and_execute_flow(
112+
&self,
113+
flow: ValidationFlow,
114+
input_value: Option<Value>,
115+
wait_for_result: bool,
116+
) -> Option<Value> {
117+
if let Some(body) = input_value.clone() {
118+
let verify_result = verify_flow(flow.clone(), body);
119+
120+
match verify_result {
121+
Ok(()) => {}
122+
Err(_err) => {
123+
return None;
124+
}
125+
};
126+
}
127+
128+
let execution_flow: ExecutionFlow = Self::convert_validation_flow(flow, input_value);
105129
let uuid = uuid::Uuid::new_v4().to_string();
106130
let topic = format!("execution.{}", uuid);
107-
let bytes = flow.encode_to_vec();
131+
let bytes = execution_flow.encode_to_vec();
108132

109133
if wait_for_result {
110134
match self.client.request(topic, bytes.into()).await {
@@ -131,33 +155,6 @@ impl AdapterStore {
131155
}
132156
}
133157

134-
/// validate_and_execute_flow
135-
///
136-
/// This function will validate the flow. If the flow is valid, it will execute (send the flow to the execution and wait for a/multiple result/s) the flow.
137-
///
138-
/// Arguments:
139-
/// - flow: The flow to be validated and executed.
140-
/// - input_value: The input value to be used for the flow execution.
141-
pub async fn validate_and_execute_flow(
142-
&self,
143-
flow: ValidationFlow,
144-
input_value: Option<Value>,
145-
) -> Option<Value> {
146-
if let Some(body) = input_value.clone() {
147-
let verify_result = verify_flow(flow.clone(), body);
148-
149-
match verify_result {
150-
Ok(()) => {}
151-
Err(_err) => {
152-
return None;
153-
}
154-
};
155-
}
156-
157-
let execution_flow: ExecutionFlow = Self::convert_validation_flow(flow, input_value);
158-
self.execute(execution_flow, true).await
159-
}
160-
161158
fn convert_validation_flow(flow: ValidationFlow, input_value: Option<Value>) -> ExecutionFlow {
162159
ExecutionFlow {
163160
flow_id: flow.flow_id,

0 commit comments

Comments
 (0)