From 92a0bff8c43591d6041dd855b4ec5923c9cd918d Mon Sep 17 00:00:00 2001 From: Dreaded_X Date: Fri, 17 Oct 2025 04:29:14 +0200 Subject: [PATCH] refactor(config)!: Move scheduler out of device_manager Due to changes made in mlua the new scheduler is much simpler. It also had no real business being part of the device manager, so it has now been moved to be part of the returned config. --- Cargo.lock | 233 ++++++++++++++++------ Cargo.toml | 5 +- automation_lib/Cargo.toml | 3 - automation_lib/src/device_manager.rs | 43 ---- automation_lib/src/lib.rs | 1 - automation_lib/src/schedule.rs | 17 -- config.lua | 20 +- definitions/automation:device_manager.lua | 4 - definitions/config.lua | 1 + src/bin/automation.rs | 3 + src/config.rs | 3 + src/lib.rs | 1 + src/schedule.rs | 28 +++ 13 files changed, 224 insertions(+), 138 deletions(-) delete mode 100644 automation_lib/src/schedule.rs create mode 100644 src/schedule.rs diff --git a/Cargo.lock b/Cargo.lock index a71f1da..0153116 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -36,12 +36,6 @@ dependencies = [ "serde", ] -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - [[package]] name = "android_system_properties" version = "0.1.5" @@ -108,6 +102,7 @@ dependencies = [ "serde_json", "thiserror 2.0.16", "tokio", + "tokio-cron-scheduler", "tracing", "tracing-subscriber", ] @@ -154,7 +149,6 @@ dependencies = [ "futures", "google_home", "hostname", - "indexmap", "inventory", "lua_typed", "mlua", @@ -163,9 +157,7 @@ dependencies = [ "serde_json", "thiserror 2.0.16", "tokio", - "tokio-cron-scheduler", "tracing", - "uuid", ] [[package]] @@ -324,16 +316,25 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.41" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ - "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "wasm-bindgen", - "windows-link", + "windows-link 0.2.1", +] + +[[package]] +name = "chrono-tz" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6139a8597ed92cf816dfb33f5dd6cf0bb93a6adc938f11039f371bc5bcd26c3" +dependencies = [ + "chrono", + "phf", ] [[package]] @@ -376,11 +377,48 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "croner" -version = "2.2.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c344b0690c1ad1c7176fe18eb173e0c927008fdaaa256e40dfd43ddd149c0843" +checksum = "4c007081651a19b42931f86f7d4f74ee1c2a7d0cd2c6636a81695b5ffd4e9990" dependencies = [ "chrono", + "derive_builder", + "strum", +] + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.106", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.106", ] [[package]] @@ -424,6 +462,37 @@ dependencies = [ "thiserror 2.0.16", ] +[[package]] +name = "derive_builder" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "derive_builder_macro" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" +dependencies = [ + "derive_builder_core", + "syn 2.0.106", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -468,12 +537,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7f84e12ccf0a7ddc17a6c41c93326024c42920d7ee630d04950e6926645c0fe" -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - [[package]] name = "erased-serde" version = "0.4.6" @@ -703,10 +766,10 @@ dependencies = [ ] [[package]] -name = "hashbrown" -version = "0.15.5" +name = "heck" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hex" @@ -722,7 +785,7 @@ checksum = "a56f203cd1c76362b69e3863fd987520ac36cf70a8c92627449b2f64a8cf7d65" dependencies = [ "cfg-if", "libc", - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -836,9 +899,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.63" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -944,6 +1007,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "1.1.0" @@ -965,17 +1034,6 @@ dependencies = [ "icu_properties", ] -[[package]] -name = "indexmap" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9" -dependencies = [ - "equivalent", - "hashbrown", - "serde", -] - [[package]] name = "inventory" version = "0.3.21" @@ -1104,16 +1162,17 @@ dependencies = [ [[package]] name = "lua_typed" version = "0.1.0" -source = "git+https://git.huizinga.dev/Dreaded_X/lua_typed#08f5c4533a93131e8eda6702c062fb841d14d4e1" +source = "git+https://git.huizinga.dev/Dreaded_X/lua_typed#f6a684291432aae2ef7109712882e7e3ed758d08" dependencies = [ "eui48", "lua_typed_macro", + "mlua", ] [[package]] name = "lua_typed_macro" version = "0.1.0" -source = "git+https://git.huizinga.dev/Dreaded_X/lua_typed#08f5c4533a93131e8eda6702c062fb841d14d4e1" +source = "git+https://git.huizinga.dev/Dreaded_X/lua_typed#f6a684291432aae2ef7109712882e7e3ed758d08" dependencies = [ "convert_case", "itertools", @@ -1209,9 +1268,9 @@ dependencies = [ [[package]] name = "mlua" -version = "0.11.3" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b3dd94c3c4dea0049b22296397040840a8f6b5b5229f438434ba82df402b42d" +checksum = "9be1c2bfc684b8a228fbaebf954af7a47a98ec27721986654a4cc2c40a20cc7e" dependencies = [ "bstr", "either", @@ -1349,6 +1408,24 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +[[package]] +name = "phf" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "913273894cec178f401a31ec4b656318d95473527be05c0752cc41cdc32be8b7" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_shared" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06005508882fb681fd97892ecff4b7fd0fee13ef1aa569f8695dae7ab9099981" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project-lite" version = "0.2.16" @@ -1901,6 +1978,12 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + [[package]] name = "slab" version = "0.4.11" @@ -1938,6 +2021,33 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "subtle" version = "2.6.1" @@ -2080,11 +2190,12 @@ dependencies = [ [[package]] name = "tokio-cron-scheduler" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c71ce8f810abc9fabebccc30302a952f9e89c6cf246fafaf170fef164063141" +checksum = "bb73c4033ddcbbf81fd828293fd41a0145cde2cbc30dd782227c5081a523214d" dependencies = [ "chrono", + "chrono-tz", "croner", "num-derive", "num-traits", @@ -2479,22 +2590,22 @@ dependencies = [ [[package]] name = "windows-core" -version = "0.61.2" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement", "windows-interface", - "windows-link", + "windows-link 0.2.1", "windows-result", "windows-strings", ] [[package]] name = "windows-implement" -version = "0.60.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", @@ -2503,9 +2614,9 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.59.1" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", @@ -2519,21 +2630,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" [[package]] -name = "windows-result" -version = "0.3.4" +name = "windows-link" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "windows-link", + "windows-link 0.2.1", ] [[package]] name = "windows-strings" -version = "0.4.2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ - "windows-link", + "windows-link 0.2.1", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index fa7f3e8..159d31b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,6 @@ futures = "0.3.31" google_home = { path = "./google_home/google_home" } google_home_macro = { path = "./google_home/google_home_macro" } hostname = "0.4.1" -indexmap = { version = "2.11.0", features = ["serde"] } inventory = "0.3.21" itertools = "0.14.0" json_value_merge = "2.0.1" @@ -59,10 +58,9 @@ serde_repr = "0.1.20" syn = { version = "2.0.106" } thiserror = "2.0.16" tokio = { version = "1", features = ["rt-multi-thread"] } -tokio-cron-scheduler = "0.14.0" +tokio-cron-scheduler = "0.15.0" tracing = "0.1.41" tracing-subscriber = "0.3.20" -uuid = "1.18.1" wakey = "0.3.0" [dependencies] @@ -87,6 +85,7 @@ serde = { workspace = true } serde_json = { workspace = true } thiserror = { workspace = true } tokio = { workspace = true } +tokio-cron-scheduler = { workspace = true } tracing = { workspace = true } tracing-subscriber = { workspace = true } diff --git a/automation_lib/Cargo.toml b/automation_lib/Cargo.toml index 15b28aa..04dea30 100644 --- a/automation_lib/Cargo.toml +++ b/automation_lib/Cargo.toml @@ -11,7 +11,6 @@ dyn-clone = { workspace = true } futures = { workspace = true } google_home = { workspace = true } hostname = { workspace = true } -indexmap = { workspace = true } inventory = { workspace = true } lua_typed = { workspace = true } mlua = { workspace = true } @@ -20,6 +19,4 @@ serde = { workspace = true } serde_json = { workspace = true } thiserror = { workspace = true } tokio = { workspace = true } -tokio-cron-scheduler = { workspace = true } tracing = { workspace = true } -uuid = { workspace = true } diff --git a/automation_lib/src/device_manager.rs b/automation_lib/src/device_manager.rs index fe755f2..cdf302a 100644 --- a/automation_lib/src/device_manager.rs +++ b/automation_lib/src/device_manager.rs @@ -1,13 +1,10 @@ use std::collections::HashMap; -use std::pin::Pin; use std::sync::Arc; -use futures::Future; use futures::future::join_all; use lua_typed::Typed; use mlua::FromLua; use tokio::sync::{RwLock, RwLockReadGuard}; -use tokio_cron_scheduler::{Job, JobScheduler}; use tracing::{debug, instrument, trace}; use crate::device::Device; @@ -19,7 +16,6 @@ pub type DeviceMap = HashMap>; pub struct DeviceManager { devices: Arc>, event_channel: EventChannel, - scheduler: JobScheduler, } impl DeviceManager { @@ -29,7 +25,6 @@ impl DeviceManager { let device_manager = Self { devices: Arc::new(RwLock::new(HashMap::new())), event_channel, - scheduler: JobScheduler::new().await.unwrap(), }; tokio::spawn({ @@ -45,8 +40,6 @@ impl DeviceManager { } }); - device_manager.scheduler.start().await.unwrap(); - device_manager } @@ -105,42 +98,6 @@ impl mlua::UserData for DeviceManager { Ok(()) }); - methods.add_async_method( - "schedule", - async |lua, this, (schedule, f): (String, mlua::Function)| { - debug!("schedule = {schedule}"); - // This creates a function, that returns the actual job we want to run - let create_job = { - let lua = lua.clone(); - - move |uuid: uuid::Uuid, - _: tokio_cron_scheduler::JobScheduler| - -> Pin + Send>> { - let lua = lua.clone(); - - // Create the actual function we want to run on a schedule - let future = async move { - let f: mlua::Function = - lua.named_registry_value(uuid.to_string().as_str()).unwrap(); - f.call_async::<()>(()).await.unwrap(); - }; - - Box::pin(future) - } - }; - - let job = Job::new_async(schedule.as_str(), create_job).unwrap(); - - let uuid = this.scheduler.add(job).await.unwrap(); - - // Store the function in the registry - lua.set_named_registry_value(uuid.to_string().as_str(), f) - .unwrap(); - - Ok(()) - }, - ); - methods.add_method("event_channel", |_lua, this, ()| Ok(this.event_channel())) } } diff --git a/automation_lib/src/lib.rs b/automation_lib/src/lib.rs index 224971a..a50fabd 100644 --- a/automation_lib/src/lib.rs +++ b/automation_lib/src/lib.rs @@ -13,7 +13,6 @@ pub mod helpers; pub mod lua; pub mod messages; pub mod mqtt; -pub mod schedule; type RegisterFn = fn(lua: &mlua::Lua) -> mlua::Result; type DefinitionsFn = fn() -> String; diff --git a/automation_lib/src/schedule.rs b/automation_lib/src/schedule.rs deleted file mode 100644 index 3300629..0000000 --- a/automation_lib/src/schedule.rs +++ /dev/null @@ -1,17 +0,0 @@ -use indexmap::IndexMap; -use serde::Deserialize; - -#[derive(Debug, Deserialize, Hash, PartialEq, Eq, Clone, Copy)] -#[serde(rename_all = "snake_case")] -pub enum Action { - On, - Off, -} - -pub type Schedule = IndexMap>>; - -// #[derive(Debug, Deserialize)] -// pub struct Schedule { -// pub when: String, -// pub actions: IndexMap>, -// } diff --git a/config.lua b/config.lua index b67a3d9..90493b9 100644 --- a/config.lua +++ b/config.lua @@ -57,7 +57,7 @@ local function check_battery(device, battery) low_battery[id] = nil end end -device_manager:schedule("0 0 21 */1 * *", function() +local function notify_low_battery() -- Don't send notifications if there are now devices with low battery if next(low_battery) == nil then print("No devices with low battery") @@ -76,7 +76,7 @@ device_manager:schedule("0 0 21 */1 * *", function() tags = { "battery" }, priority = "default", }) -end) +end --- @class OnPresence --- @field [integer] fun(presence: boolean) @@ -742,17 +742,19 @@ devs:add(devices.ContactSensor.new({ battery_callback = check_battery, })) -device_manager:schedule("0 0 19 * * *", function() - bedroom_air_filter:set_on(true) -end) -device_manager:schedule("0 0 20 * * *", function() - bedroom_air_filter:set_on(false) -end) - ---@type Config return { fulfillment = { openid_url = "https://login.huizinga.dev/api/oidc", }, devices = devs, + schedule = { + ["0 0 19 * * *"] = function() + bedroom_air_filter:set_on(true) + end, + ["0 0 20 * * *"] = function() + bedroom_air_filter:set_on(false) + end, + ["0 0 21 */1 * *"] = notify_low_battery, + }, } diff --git a/definitions/automation:device_manager.lua b/definitions/automation:device_manager.lua index 9fa74fc..23af2c8 100644 --- a/definitions/automation:device_manager.lua +++ b/definitions/automation:device_manager.lua @@ -5,8 +5,4 @@ local DeviceManager ---@param device DeviceInterface function DeviceManager:add(device) end ----@param cron string ----@param callback fun() -function DeviceManager:schedule(cron, callback) end - return DeviceManager diff --git a/definitions/config.lua b/definitions/config.lua index 346d45a..9892431 100644 --- a/definitions/config.lua +++ b/definitions/config.lua @@ -10,4 +10,5 @@ local FulfillmentConfig ---@class Config ---@field fulfillment FulfillmentConfig ---@field devices DeviceInterface[]? +---@field schedule table? local Config diff --git a/src/bin/automation.rs b/src/bin/automation.rs index a0cd914..644e94a 100644 --- a/src/bin/automation.rs +++ b/src/bin/automation.rs @@ -6,6 +6,7 @@ use std::process; use ::config::{Environment, File}; use automation::config::{Config, Setup}; +use automation::schedule::start_scheduler; use automation::secret::EnvironmentSecretFile; use automation::version::VERSION; use automation::web::{ApiError, User}; @@ -142,6 +143,8 @@ async fn app() -> anyhow::Result<()> { device_manager.add(device).await; } + start_scheduler(config.schedule).await?; + // Create google home fulfillment route let fulfillment = Router::new().route("/google_home", post(fulfillment)); diff --git a/src/config.rs b/src/config.rs index 2875164..2360daf 100644 --- a/src/config.rs +++ b/src/config.rs @@ -37,6 +37,9 @@ pub struct Config { #[device_config(from_lua, default)] #[typed(default)] pub devices: Vec>, + #[device_config(from_lua, default)] + #[typed(default)] + pub schedule: HashMap, } impl From for SocketAddr { diff --git a/src/lib.rs b/src/lib.rs index 49e787e..f1e947d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,5 @@ pub mod config; +pub mod schedule; pub mod secret; pub mod version; pub mod web; diff --git a/src/schedule.rs b/src/schedule.rs new file mode 100644 index 0000000..62a90ad --- /dev/null +++ b/src/schedule.rs @@ -0,0 +1,28 @@ +use std::collections::HashMap; +use std::pin::Pin; + +use tokio_cron_scheduler::{Job, JobScheduler, JobSchedulerError}; + +pub async fn start_scheduler( + schedule: HashMap, +) -> Result<(), JobSchedulerError> { + let scheduler = JobScheduler::new().await?; + + for (s, f) in schedule { + let job = { + move |_uuid, _lock| -> Pin + Send>> { + let f = f.clone(); + + Box::pin(async move { + f.call_async::<()>(()).await.unwrap(); + }) + } + }; + + let job = Job::new_async(s, job)?; + + scheduler.add(job).await?; + } + + scheduler.start().await +}