mirror of
https://github.com/lune-org/lune.git
synced 2025-04-10 21:40:54 +01:00
impl cache
This commit is contained in:
parent
a633afc828
commit
fedaf9a625
1 changed files with 73 additions and 3 deletions
|
@ -3,7 +3,10 @@ use mlua::prelude::*;
|
||||||
use std::{collections::HashMap, path::PathBuf, sync::Arc};
|
use std::{collections::HashMap, path::PathBuf, sync::Arc};
|
||||||
use tokio::{
|
use tokio::{
|
||||||
fs,
|
fs,
|
||||||
sync::{broadcast::Sender, Mutex},
|
sync::{
|
||||||
|
broadcast::{self, Sender},
|
||||||
|
Mutex,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The private struct that's stored in mlua's app data container
|
/// The private struct that's stored in mlua's app data container
|
||||||
|
@ -78,6 +81,48 @@ impl RequireContext {
|
||||||
path_rel: PathBuf,
|
path_rel: PathBuf,
|
||||||
path_abs: PathBuf,
|
path_abs: PathBuf,
|
||||||
) -> LuaResult<LuaMultiValue> {
|
) -> 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? {
|
if !fs::try_exists(&path_abs).await? {
|
||||||
return Err(LuaError::runtime(format!(
|
return Err(LuaError::runtime(format!(
|
||||||
"Can not require '{}' as it does not exist",
|
"Can not require '{}' as it does not exist",
|
||||||
|
@ -87,10 +132,35 @@ impl RequireContext {
|
||||||
|
|
||||||
let content = fs::read_to_string(&path_abs).await?;
|
let content = fs::read_to_string(&path_abs).await?;
|
||||||
|
|
||||||
lua.load(content)
|
let multi = lua
|
||||||
|
.load(content)
|
||||||
.set_name(path_abs.to_string_lossy())
|
.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
|
.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(
|
pub fn inject_std(
|
||||||
|
|
Loading…
Add table
Reference in a new issue