diff --git a/Cargo.lock b/Cargo.lock index 94dcd43..80b3127 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -109,7 +109,6 @@ dependencies = [ "impls", "indexmap 2.2.6", "mlua", - "once_cell", "paste", "pollster", "regex", diff --git a/Cargo.toml b/Cargo.toml index a81d72d..5c3ab19 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,7 +56,6 @@ mlua = { version = "0.10.1", features = [ "async", "send", ] } -once_cell = "1.19.0" hostname = "0.4.0" tokio-util = { version = "0.7.11", features = ["full"] } uuid = "1.8.0" diff --git a/src/device_manager.rs b/src/device_manager.rs index 70523d9..789cd79 100644 --- a/src/device_manager.rs +++ b/src/device_manager.rs @@ -6,12 +6,10 @@ use futures::future::join_all; use futures::Future; use tokio::sync::{RwLock, RwLockReadGuard}; use tokio_cron_scheduler::{Job, JobScheduler}; -use tokio_util::task::LocalPoolHandle; use tracing::{debug, instrument, trace}; use crate::devices::Device; use crate::event::{Event, EventChannel, OnDarkness, OnMqtt, OnNotification, OnPresence}; -use crate::LUA; pub type DeviceMap = HashMap>; @@ -142,23 +140,6 @@ impl DeviceManager { } } -fn run_schedule( - uuid: uuid::Uuid, - _: tokio_cron_scheduler::JobScheduler, -) -> Pin + Send>> { - Box::pin(async move { - // Lua is not Send, so we need to make sure that the task stays on the same thread - let pool = LocalPoolHandle::new(1); - pool.spawn_pinned(move || async move { - let lua = LUA.lock().await; - let f: mlua::Function = lua.named_registry_value(uuid.to_string().as_str()).unwrap(); - f.call_async::<()>(()).await.unwrap(); - }) - .await - .unwrap(); - }) -} - impl mlua::UserData for DeviceManager { fn add_methods>(methods: &mut M) { methods.add_async_method("add", |_lua, this, device: Box| async move { @@ -171,7 +152,27 @@ impl mlua::UserData for DeviceManager { "schedule", |lua, this, (schedule, f): (String, mlua::Function)| async move { debug!("schedule = {schedule}"); - let job = Job::new_async(schedule.as_str(), run_schedule).unwrap(); + // 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(); @@ -183,12 +184,6 @@ impl mlua::UserData for DeviceManager { }, ); - // methods.add_async_method("add_schedule", |lua, this, schedule| async { - // let schedule = lua.from_value(schedule)?; - // this.add_schedule(schedule).await; - // Ok(()) - // }); - methods.add_method("event_channel", |_lua, this, ()| Ok(this.event_channel())) } } diff --git a/src/lib.rs b/src/lib.rs index b04db7f..3cbd2de 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,8 +2,6 @@ #![feature(specialization)] #![feature(let_chains)] -use once_cell::sync::Lazy; -use tokio::sync::Mutex; pub mod auth; pub mod config; pub mod device_manager; @@ -14,5 +12,3 @@ pub mod messages; pub mod mqtt; pub mod schedule; pub mod traits; - -pub static LUA: Lazy> = Lazy::new(|| Mutex::new(mlua::Lua::new())); diff --git a/src/main.rs b/src/main.rs index deec0fa..24ba0be 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,9 +5,9 @@ use anyhow::anyhow; use automation::auth::User; use automation::config::{FulfillmentConfig, MqttConfig}; use automation::device_manager::DeviceManager; +use automation::devices; use automation::error::ApiError; use automation::mqtt::{self, WrappedAsyncClient}; -use automation::{devices, LUA}; use axum::extract::{FromRef, State}; use axum::http::StatusCode; use axum::routing::post; @@ -73,7 +73,7 @@ async fn app() -> anyhow::Result<()> { let device_manager = DeviceManager::new().await; let fulfillment_config = { - let lua = LUA.lock().await; + let lua = mlua::Lua::new(); lua.set_warning_function(|_lua, text, _cont| { warn!("{text}");