use std::collections::HashMap;
use std::str::FromStr;
use std::sync::{LazyLock, RwLock};
use valkey_module::alloc::ValkeyAlloc;
use valkey_module::{valkey_module, Context, Status, ValkeyString};
use valkey_module_macros::cron_event_handler;
#[derive(Debug)]
struct EnvConfig {
cron_fn1_fn2: String,
cron_fn3: String,
}
impl EnvConfig {
pub(crate) fn new(env: &str) -> Self {
let output = match env {
"dev" => EnvConfig {
cron_fn1_fn2: "*/5 * * * * * *".to_string(),
cron_fn3: "*/10 * * * * * *".to_string(),
},
_ => EnvConfig {
cron_fn1_fn2: "*/15 * * * * * *".to_string(),
cron_fn3: "*/30 * * * * * *".to_string(),
},
};
output
}
}
static ENV_CONFIG: LazyLock<RwLock<EnvConfig>> = LazyLock::new(|| RwLock::new(EnvConfig::new("")));
static CRONTAB: LazyLock<HashMap<String, Vec<fn(&Context)>>> = LazyLock::new(|| {
let env_config = ENV_CONFIG.read().unwrap();
let mut output = HashMap::new();
output.insert(
env_config.cron_fn1_fn2.clone(),
vec![cron_fn1 as fn(&Context), cron_fn2 as fn(&Context)],
);
output.insert(env_config.cron_fn3.clone(), vec![cron_fn3 as fn(&Context)]);
output
});
fn cron_fn1(_ctx: &Context) {
}
fn cron_fn2(_ctx: &Context) {
}
fn cron_fn3(_ctx: &Context) {
}
#[cron_event_handler]
fn cron_event_handler(ctx: &Context, _hz: u64) {
let hz = match ctx.config_get("hz".to_string()) {
Ok(tmp) => tmp.to_string().parse::<u64>().unwrap_or(10),
Err(_) => 10, };
let interval = 1000 / hz as i64;
for (expression, functions) in CRONTAB.iter() {
let schedule = cron::Schedule::from_str(expression).unwrap();
let next_time = schedule.upcoming(chrono::Utc).next().unwrap_or_default();
let now = chrono::Utc::now();
if next_time.timestamp_millis() <= now.timestamp_millis() + interval {
for function in functions {
function(ctx);
}
}
}
}
fn initialize(ctx: &Context, args: &[ValkeyString]) -> Status {
let env_name = match args.get(0) {
Some(tmp) => tmp.to_string(),
None => "".to_string(),
};
let mut guard = ENV_CONFIG.write().unwrap();
*guard = EnvConfig::new(env_name.as_str());
drop(guard);
ctx.log_notice(&format!(
"env_name, {:?}, ENV_CONFIG: {:?}",
env_name, ENV_CONFIG
));
Status::Ok
}
valkey_module! {
name: "crontab",
version: 1,
allocator: (ValkeyAlloc, ValkeyAlloc),
data_types: [],
init: initialize,
commands: [
],
}