mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
perf: lazy compile and cache lua plugins as binary bytecode (#2490)
This commit is contained in:
parent
8b3ce1838a
commit
c5808a0db4
9 changed files with 54 additions and 48 deletions
|
|
@ -4,7 +4,7 @@ const RE_DEPENDENCIES = /Dependencies\s+[/a-z]+\s*:\s/gm
|
|||
const RE_CHECKLIST = /#{3}\s+Checklist\s+(?:^-\s+\[x]\s+.+?(?:\n|\r\n|$)){2}/gm
|
||||
|
||||
function bugReportBody(creator, content, hash) {
|
||||
if (RE_CHECKLIST.test(content) && new RegExp(` \\(${hash}[a-z]? `).test(content)) {
|
||||
if (RE_DEPENDENCIES.test(content) && RE_CHECKLIST.test(content) && new RegExp(` \\(${hash}[a-z]? `).test(content)) {
|
||||
return null
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ pub(super) struct Logs;
|
|||
impl Logs {
|
||||
pub(super) fn start() -> anyhow::Result<()> {
|
||||
let level = LOG_LEVEL.get();
|
||||
if LOG_LEVEL.get().is_none() {
|
||||
if level.is_none() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use mlua::{ExternalError, ExternalResult, ObjectLike, Table};
|
||||
use mlua::{ExternalResult, ObjectLike};
|
||||
use tokio::runtime::Handle;
|
||||
use yazi_dds::Sendable;
|
||||
use yazi_proxy::options::PluginOpt;
|
||||
|
|
@ -11,14 +11,9 @@ pub async fn entry(opt: PluginOpt) -> mlua::Result<()> {
|
|||
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let lua = slim_lua(&opt.id)?;
|
||||
let plugin: Table = if let Some(c) = LOADER.read().get(opt.id.as_ref()) {
|
||||
lua.load(c.as_bytes()).set_name(opt.id.as_ref()).call(())?
|
||||
} else {
|
||||
return Err("unloaded plugin".into_lua_err());
|
||||
};
|
||||
let plugin = LOADER.load_once(&lua, &opt.id)?;
|
||||
|
||||
let job = lua.create_table_from([("args", Sendable::args_to_table(&lua, opt.args)?)])?;
|
||||
|
||||
Handle::current().block_on(plugin.call_async_method("entry", job))
|
||||
})
|
||||
.await
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use mlua::{ExternalError, ExternalResult, FromLua, IntoLua, Lua, ObjectLike, Table, Value};
|
||||
use mlua::{ExternalResult, FromLua, IntoLua, Lua, ObjectLike, Value};
|
||||
use tokio::runtime::Handle;
|
||||
use yazi_dds::Sendable;
|
||||
use yazi_shared::event::CmdCow;
|
||||
|
|
@ -17,11 +17,7 @@ pub async fn fetch(
|
|||
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let lua = slim_lua(&cmd.name)?;
|
||||
let plugin: Table = if let Some(c) = LOADER.read().get(&cmd.name) {
|
||||
lua.load(c.as_bytes()).set_name(&cmd.name).call(())?
|
||||
} else {
|
||||
return Err("unloaded plugin".into_lua_err());
|
||||
};
|
||||
let plugin = LOADER.load_once(&lua, &cmd.name)?;
|
||||
|
||||
Handle::current().block_on(plugin.call_async_method(
|
||||
"fetch",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use mlua::{ExternalError, HookTriggers, IntoLua, ObjectLike, Table, VmState};
|
||||
use mlua::{ExternalError, HookTriggers, IntoLua, ObjectLike, VmState};
|
||||
use tokio::{runtime::Handle, select};
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tracing::error;
|
||||
|
|
@ -84,12 +84,7 @@ fn peek_async(
|
|||
},
|
||||
);
|
||||
|
||||
let plugin: Table = if let Some(c) = LOADER.read().get(&cmd.name) {
|
||||
lua.load(c.as_bytes()).set_name(&cmd.name).call(())?
|
||||
} else {
|
||||
return Err("unloaded plugin".into_lua_err());
|
||||
};
|
||||
|
||||
let plugin = LOADER.load_once(&lua, &cmd.name)?;
|
||||
let job = lua.create_table_from([
|
||||
("area", Rect::from(LAYOUT.get().preview).into_lua(&lua)?),
|
||||
("args", Sendable::args_to_table_ref(&lua, &cmd.args)?.into_lua(&lua)?),
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use mlua::{ExternalError, ExternalResult, IntoLua, ObjectLike, Table};
|
||||
use mlua::{ExternalResult, IntoLua, ObjectLike};
|
||||
use tokio::runtime::Handle;
|
||||
use yazi_config::LAYOUT;
|
||||
use yazi_dds::Sendable;
|
||||
|
|
@ -15,11 +15,7 @@ pub async fn preload(
|
|||
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let lua = slim_lua(&cmd.name)?;
|
||||
let plugin: Table = if let Some(b) = LOADER.read().get(&cmd.name) {
|
||||
lua.load(b.as_bytes()).set_name(&cmd.name).call(())?
|
||||
} else {
|
||||
return Err("unloaded plugin".into_lua_err());
|
||||
};
|
||||
let plugin = LOADER.load_once(&lua, &cmd.name)?;
|
||||
|
||||
let job = lua.create_table_from([
|
||||
("area", Rect::from(LAYOUT.get().preview).into_lua(&lua)?),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use mlua::{ExternalError, ExternalResult, HookTriggers, IntoLua, ObjectLike, Table, VmState};
|
||||
use mlua::{ExternalError, ExternalResult, HookTriggers, IntoLua, ObjectLike, VmState};
|
||||
use tokio::{runtime::Handle, select};
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tracing::error;
|
||||
|
|
@ -35,18 +35,14 @@ pub fn spot(
|
|||
},
|
||||
);
|
||||
|
||||
let plugin: Table = if let Some(b) = LOADER.read().get(&cmd.name) {
|
||||
lua.load(b.as_bytes()).set_name(&cmd.name).call(())?
|
||||
} else {
|
||||
return Err("unloaded plugin".into_lua_err());
|
||||
};
|
||||
|
||||
let plugin = LOADER.load_once(&lua, &cmd.name)?;
|
||||
let job = lua.create_table_from([
|
||||
("args", Sendable::args_to_table_ref(&lua, &cmd.args)?.into_lua(&lua)?),
|
||||
("file", File(file).into_lua(&lua)?),
|
||||
("mime", mime.into_lua(&lua)?),
|
||||
("skip", skip.into_lua(&lua)?),
|
||||
])?;
|
||||
|
||||
if ct2.is_cancelled() { Ok(()) } else { plugin.call_async_method("spot", job).await }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use mlua::{AsChunk, ChunkMode};
|
||||
use yazi_shared::natsort;
|
||||
|
||||
pub struct Chunk {
|
||||
pub mode: ChunkMode,
|
||||
pub bytes: Cow<'static, [u8]>,
|
||||
pub since: String,
|
||||
pub sync_peek: bool,
|
||||
|
|
@ -10,9 +12,6 @@ pub struct Chunk {
|
|||
}
|
||||
|
||||
impl Chunk {
|
||||
#[inline]
|
||||
pub fn as_bytes(&self) -> &[u8] { &self.bytes }
|
||||
|
||||
#[inline]
|
||||
pub fn compatible(&self) -> bool {
|
||||
let s = yazi_boot::actions::Actions::version();
|
||||
|
|
@ -46,8 +45,13 @@ impl Chunk {
|
|||
|
||||
impl From<Cow<'static, [u8]>> for Chunk {
|
||||
fn from(b: Cow<'static, [u8]>) -> Self {
|
||||
let mut chunk =
|
||||
Self { bytes: b, since: String::new(), sync_entry: false, sync_peek: false };
|
||||
let mut chunk = Self {
|
||||
mode: ChunkMode::Text,
|
||||
bytes: b,
|
||||
since: String::new(),
|
||||
sync_entry: false,
|
||||
sync_peek: false,
|
||||
};
|
||||
chunk.analyze();
|
||||
chunk
|
||||
}
|
||||
|
|
@ -60,3 +64,9 @@ impl From<&'static [u8]> for Chunk {
|
|||
impl From<Vec<u8>> for Chunk {
|
||||
fn from(b: Vec<u8>) -> Self { Self::from(Cow::Owned(b)) }
|
||||
}
|
||||
|
||||
impl<'a> AsChunk<'a> for &'a Chunk {
|
||||
fn source(self) -> std::io::Result<Cow<'a, [u8]>> { Ok(Cow::Borrowed(&self.bytes)) }
|
||||
|
||||
fn mode(&self) -> Option<ChunkMode> { Some(self.mode) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::{collections::HashMap, ops::Deref};
|
||||
use std::{borrow::Cow, collections::HashMap, ops::Deref};
|
||||
|
||||
use anyhow::{Context, Result, bail};
|
||||
use mlua::{ExternalError, Lua, Table};
|
||||
use mlua::{ChunkMode, ExternalError, Lua, Table};
|
||||
use parking_lot::RwLock;
|
||||
use tokio::fs;
|
||||
use yazi_boot::BOOT;
|
||||
|
|
@ -75,16 +75,34 @@ impl Loader {
|
|||
return Ok(t);
|
||||
}
|
||||
|
||||
let t: Table = match self.read().get(id) {
|
||||
Some(c) => lua.load(c.as_bytes()).set_name(id).call(())?,
|
||||
None => Err(format!("plugin `{id}` not found").into_lua_err())?,
|
||||
};
|
||||
|
||||
let t = self.load_once(lua, id)?;
|
||||
t.raw_set("_id", lua.create_string(id)?)?;
|
||||
|
||||
loaded.raw_set(id, t.clone())?;
|
||||
Ok(t)
|
||||
}
|
||||
|
||||
pub fn load_once(&self, lua: &Lua, id: &str) -> mlua::Result<Table> {
|
||||
let mut mode = ChunkMode::Text;
|
||||
let f = match self.read().get(id) {
|
||||
Some(c) => {
|
||||
mode = c.mode;
|
||||
lua.load(c).set_name(id).into_function()
|
||||
}
|
||||
None => Err(format!("plugin `{id}` not found").into_lua_err()),
|
||||
}?;
|
||||
|
||||
if mode != ChunkMode::Binary {
|
||||
let b = f.dump(true);
|
||||
if let Some(c) = self.write().get_mut(id) {
|
||||
c.mode = ChunkMode::Binary;
|
||||
c.bytes = Cow::Owned(b);
|
||||
}
|
||||
}
|
||||
|
||||
f.call(())
|
||||
}
|
||||
|
||||
pub fn try_load(&self, lua: &Lua, id: &str) -> mlua::Result<Table> {
|
||||
lua.globals().raw_get::<Table>("package")?.raw_get::<Table>("loaded")?.raw_get(id)
|
||||
}
|
||||
|
|
@ -95,7 +113,7 @@ impl Loader {
|
|||
return Ok(t);
|
||||
}
|
||||
|
||||
let t: Table = lua.load(chunk.as_bytes()).set_name(id).call(())?;
|
||||
let t: Table = lua.load(chunk).set_name(id).call(())?;
|
||||
t.raw_set("_id", lua.create_string(id)?)?;
|
||||
|
||||
loaded.raw_set(id, t.clone())?;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue