use std::time::Duration;
use reqwest::{Method};
use tokio_cron::{Job, Scheduler};
use crate::configure::get_jobs;
use crate::models::http_job::HttpJob;
use crate::utils::datetime_util::{get_local_datetime_in_timezone};
use crate::utils::uuid_util::generate_uuid_without_hyphens;
pub async fn start_cron_scheduler() {
let jobs = get_jobs();
let http_jobs = &jobs.http_jobs;
let mut scheduler = Scheduler::new_in_timezone(jobs.timezone);
for it in http_jobs {
if it.enable {
let job = Job::new_sync(&it.cron, move || {
tokio::spawn(start_http_job(it));
});
scheduler.add(job);
}
}
}
async fn start_http_job(http_job: &HttpJob) {
let jobs = get_jobs();
let timezone = &jobs.timezone;
let uuid = generate_uuid_without_hyphens();
let local_time = get_local_datetime_in_timezone(timezone);
println!("{} {} Http job start, job name: {}", uuid, local_time, &http_job.name);
println!("{} {} Job: [{}]", uuid, local_time, &http_job);
let request = &http_job.request;
let method = get_method(&request.method);
let timeout = http_job.timeout.clone();
let client = reqwest::Client::builder()
.user_agent("rjob")
.timeout(Duration::from_millis(timeout))
.build()
.expect("Failed to create HTTP client");
let mut attempts = 0;
let max_attempts = http_job.max_retry.clone();
while attempts < max_attempts {
attempts += 1;
let request_builder = client.request(method.clone(), &request.url)
.header("Content-Type", "application/json")
.headers(request.headers.clone().unwrap_or_default())
.body(request.body.clone().unwrap_or_default());
let resp = match request_builder.send().await {
Ok(resp) => resp,
Err(err) => {
println!("{} {} Http request failed, job name: {}, error: {}. Retry attempt: {}/{}", uuid, local_time, &http_job.name, err, attempts, max_attempts);
continue;
}
};
let status = resp.status();
let text = resp.text().await.unwrap();
if status.is_success() {
println!("{} {} Http request success, job name: {}", uuid, local_time, &http_job.name);
println!("{} {} Http response: {}", uuid, local_time, text);
} else {
println!("{} {} Http request failed, job name: {}, http status: {}", uuid, local_time, &http_job.name, status.as_u16());
println!("{} {} Http response: {}", uuid, local_time, text);
}
break;
}
println!("{} {} Http job end, job name: {}\n", uuid, local_time, &http_job.name);
}
fn get_method(method: &str) -> Method {
match method.to_lowercase().as_str() {
"get" => Method::GET,
"post" => Method::POST,
"put" => Method::PUT,
"patch" => Method::PATCH,
"options" => Method::OPTIONS,
"delete" => Method::DELETE,
"head" => Method::HEAD,
_ => Method::GET
}
}