diff --git a/config/docs/yazi.md b/config/docs/yazi.md index 95a94a66..f4201e39 100644 --- a/config/docs/yazi.md +++ b/config/docs/yazi.md @@ -73,3 +73,9 @@ Available rule parameters are as follows: - name: Glob expression for matching the file name - mime: Glob expression for matching the MIME type - use: Opener name corresponding to the names in the opener section. + +## tasks + +- micro_workers: Maximum number of concurrent micro-tasks +- macro_workers: Maximum number of concurrent macro-tasks +- bizarre_retry: Maximum number of retries when a bizarre failure occurs diff --git a/config/preset/yazi.toml b/config/preset/yazi.toml index e3a4aa77..1d2d6ac1 100644 --- a/config/preset/yazi.toml +++ b/config/preset/yazi.toml @@ -59,5 +59,10 @@ rules = [ { mime = "*", use = "fallback" }, ] +[tasks] +micro_workers = 5 +macro_workers = 10 +bizarre_retry = 5 + [log] enabled = false diff --git a/config/src/lib.rs b/config/src/lib.rs index af5a5fa7..19df1a8d 100644 --- a/config/src/lib.rs +++ b/config/src/lib.rs @@ -10,6 +10,7 @@ pub mod open; mod pattern; mod preset; pub mod preview; +pub mod tasks; pub mod theme; pub(crate) use pattern::*; @@ -25,6 +26,7 @@ pub static LOG: Lazy = Lazy::new(Default::default); pub static MANAGER: Lazy = Lazy::new(Default::default); pub static OPEN: Lazy = Lazy::new(Default::default); pub static PREVIEW: Lazy = Lazy::new(Default::default); +pub static TASKS: Lazy = Lazy::new(Default::default); pub static THEME: Lazy = Lazy::new(Default::default); pub fn init() { @@ -34,5 +36,6 @@ pub fn init() { Lazy::force(&MANAGER); Lazy::force(&OPEN); Lazy::force(&PREVIEW); + Lazy::force(&TASKS); Lazy::force(&THEME); } diff --git a/config/src/tasks/mod.rs b/config/src/tasks/mod.rs new file mode 100644 index 00000000..217c728e --- /dev/null +++ b/config/src/tasks/mod.rs @@ -0,0 +1,3 @@ +mod tasks; + +pub use tasks::*; diff --git a/config/src/tasks/tasks.rs b/config/src/tasks/tasks.rs new file mode 100644 index 00000000..5914332c --- /dev/null +++ b/config/src/tasks/tasks.rs @@ -0,0 +1,26 @@ +use serde::Deserialize; + +use crate::MERGED_YAZI; + +#[derive(Debug, Deserialize)] +pub struct Tasks { + pub micro_workers: u8, + pub macro_workers: u8, + pub bizarre_retry: u8, +} + +impl Default for Tasks { + fn default() -> Self { + #[derive(Deserialize)] + struct Outer { + tasks: Tasks, + } + + let tasks = toml::from_str::(&MERGED_YAZI).unwrap().tasks; + if tasks.micro_workers <= 2 || tasks.macro_workers <= 2 { + panic!("micro_workers, and macro_workers must be greater than 2"); + } + + tasks + } +} diff --git a/core/src/tasks/scheduler.rs b/core/src/tasks/scheduler.rs index 22efa69b..ac2ca0d2 100644 --- a/core/src/tasks/scheduler.rs +++ b/core/src/tasks/scheduler.rs @@ -1,7 +1,7 @@ use std::{ffi::OsStr, path::PathBuf, sync::Arc, time::Duration}; use async_channel::{Receiver, Sender}; -use config::open::Opener; +use config::{open::Opener, TASKS}; use futures::{future::BoxFuture, FutureExt}; use parking_lot::RwLock; use shared::{unique_path, Throttle}; @@ -34,10 +34,10 @@ impl Scheduler { running: Default::default(), }; - for _ in 0..5 { + for _ in 0..TASKS.micro_workers { scheduler.schedule_micro(todo_rx.clone()); } - for _ in 0..5 { + for _ in 0..TASKS.macro_workers { scheduler.schedule_macro(todo_rx.clone()); } scheduler.progress(prog_rx); @@ -77,8 +77,6 @@ impl Scheduler { } if let Err(e) = file.work(&mut op).await { info!("Failed to work on task {:?}: {e}", op); - } else { - trace!("Finished task {:?}", op); } } Ok((id, mut op)) = precache.recv() => { @@ -88,8 +86,6 @@ impl Scheduler { } if let Err(e) = precache.work(&mut op).await { info!("Failed to work on task {:?}: {e}", op); - } else { - trace!("Finished task {:?}", op); } } } diff --git a/core/src/tasks/workers/file.rs b/core/src/tasks/workers/file.rs index fce5dfbf..1551ace1 100644 --- a/core/src/tasks/workers/file.rs +++ b/core/src/tasks/workers/file.rs @@ -1,6 +1,7 @@ use std::{collections::VecDeque, fs::Metadata, path::{Path, PathBuf}}; use anyhow::Result; +use config::TASKS; use futures::{future::BoxFuture, FutureExt}; use shared::{calculate_size, copy_with_progress}; use tokio::{fs, io::{self, ErrorKind::{AlreadyExists, NotFound}}, sync::mpsc}; @@ -99,7 +100,10 @@ impl File { } // Operation not permitted (os error 1) // Attribute not found (os error 93) - Err(e) if task.retry < 3 && matches!(e.raw_os_error(), Some(1) | Some(93)) => { + Err(e) + if task.retry < TASKS.bizarre_retry + && matches!(e.raw_os_error(), Some(1) | Some(93)) => + { self.log(task.id, format!("Paste task retry: {:?}", task))?; task.retry += 1; return Ok(self.tx.send(FileOp::Paste(task.clone())).await?); @@ -224,10 +228,8 @@ impl File { self.sch.send(TaskOp::New(task.id, meta.len()))?; if meta.is_file() { - trace!("Paste: {:?} -> {:?}", task.from, task.to); self.tx.send(FileOp::Paste(task.clone())).await?; } else if meta.is_symlink() { - trace!("Link: {:?} -> {:?}", task.from, task.to); self.tx.send(FileOp::Link(task.to_link(meta.len()))).await?; } } @@ -291,7 +293,6 @@ impl File { } pub(crate) fn remove_empty_dirs(dir: &Path) -> BoxFuture<()> { - trace!("Remove empty dirs: {:?}", dir); async move { let mut it = match fs::read_dir(dir).await { Ok(it) => it,