No more global LUA
All checks were successful
Build and deploy / Build application (push) Successful in 3m45s
Build and deploy / Build container (push) Successful in 54s
Build and deploy / Deploy container (push) Successful in 29s

This commit is contained in:
Dreaded_X 2024-11-30 05:10:40 +01:00
parent ae2c27551f
commit 8b04435537
Signed by: Dreaded_X
GPG Key ID: FA5F485356B0D2D4
5 changed files with 23 additions and 34 deletions

1
Cargo.lock generated
View File

@ -109,7 +109,6 @@ dependencies = [
"impls",
"indexmap 2.2.6",
"mlua",
"once_cell",
"paste",
"pollster",
"regex",

View File

@ -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"

View File

@ -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<String, Box<dyn Device>>;
@ -142,23 +140,6 @@ impl DeviceManager {
}
}
fn run_schedule(
uuid: uuid::Uuid,
_: tokio_cron_scheduler::JobScheduler,
) -> Pin<Box<dyn Future<Output = ()> + 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<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
methods.add_async_method("add", |_lua, this, device: Box<dyn Device>| 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<Box<dyn Future<Output = ()> + 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()))
}
}

View File

@ -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<Mutex<mlua::Lua>> = Lazy::new(|| Mutex::new(mlua::Lua::new()));

View File

@ -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}");