impl cache

This commit is contained in:
highflowey 2024-08-23 04:06:46 +03:30
parent a633afc828
commit fedaf9a625

View file

@ -3,7 +3,10 @@ use mlua::prelude::*;
use std::{collections::HashMap, path::PathBuf, sync::Arc};
use tokio::{
fs,
sync::{broadcast::Sender, Mutex},
sync::{
broadcast::{self, Sender},
Mutex,
},
};
/// The private struct that's stored in mlua's app data container
@ -78,6 +81,48 @@ impl RequireContext {
path_rel: PathBuf,
path_abs: PathBuf,
) -> LuaResult<LuaMultiValue> {
// wait for module to be required
// if its pending somewhere else
{
let data_ref = lua
.app_data_ref::<RequireContextData>()
.ok_or(LuaError::runtime("Couldn't find RequireContextData in app data container, make sure RequireStorage::init is called on this lua instance"))?;
let pending = data_ref.pending.try_lock().into_lua_err()?;
if let Some(a) = pending.get(&path_abs) {
a.subscribe().recv().await.into_lua_err()?;
}
}
// get module from cache
// *if* its cached
{
let data_ref = lua
.app_data_ref::<RequireContextData>()
.ok_or(LuaError::runtime("Couldn't find RequireContextData in app data container, make sure RequireStorage::init is called on this lua instance"))?;
let cache = data_ref.cache.lock().await;
if let Some(cached) = cache.get(&path_abs) {
return cached.into_lua(lua).into_lua_multi(lua);
}
}
// create a broadcast channel
{
let data_ref = lua
.app_data_ref::<RequireContextData>()
.ok_or(LuaError::runtime("Couldn't find RequireContextData in app data container, make sure RequireStorage::init is called on this lua instance"))?;
let (broadcast_tx, _) = broadcast::channel(1);
{
let mut pending = data_ref.pending.try_lock().into_lua_err()?;
pending.insert(path_abs.clone(), broadcast_tx);
}
}
if !fs::try_exists(&path_abs).await? {
return Err(LuaError::runtime(format!(
"Can not require '{}' as it does not exist",
@ -87,10 +132,35 @@ impl RequireContext {
let content = fs::read_to_string(&path_abs).await?;
lua.load(content)
let multi = lua
.load(content)
.set_name(path_abs.to_string_lossy())
.eval_async()
.eval_async::<LuaMultiValue>()
.await?;
let mutli_clone = multi.clone();
let multi_reg = lua.create_registry_value(mutli_clone.into_vec())?;
let data_ref = lua
.app_data_ref::<RequireContextData>()
.ok_or(LuaError::runtime("Couldn't find RequireContextData in app data container, make sure RequireStorage::init is called on this lua instance"))?;
data_ref
.cache
.lock()
.await
.insert(path_abs.clone(), multi_reg);
let broadcast_tx = data_ref
.pending
.lock()
.await
.remove(&path_abs)
.expect("Pending require broadcaster was unexpectedly removed");
broadcast_tx.send(()).ok();
Ok(multi)
}
pub fn inject_std(