diff --git a/Cargo.lock b/Cargo.lock index 1cb3aa75..32898d3e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -38,12 +38,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "aligned-vec" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4aa90d7ce82d4be67b64039a3d588d38dbcc6736577de4a847025ce5b0c468d1" - [[package]] name = "allocator-api2" version = "0.2.16" @@ -130,35 +124,12 @@ version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" -[[package]] -name = "arbitrary" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" - [[package]] name = "arc-swap" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b3d0060af21e8d11a926981cc00c6c1541aa91dd64b9f881985c3da1094425f" -[[package]] -name = "arg_enum_proc_macro" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "arrayvec" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" - [[package]] name = "async-priority-channel" version = "0.2.0" @@ -174,29 +145,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "av1-grain" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf" -dependencies = [ - "anyhow", - "arrayvec", - "log", - "nom", - "num-rational", - "v_frame", -] - -[[package]] -name = "avif-serialize" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876c75a42f6364451a033496a14c44bffe41f5f4a8236f697391f11024e596d2" -dependencies = [ - "arrayvec", -] - [[package]] name = "backtrace" version = "0.3.69" @@ -261,12 +209,6 @@ version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" -[[package]] -name = "bitstream-io" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06c9989a51171e2e81038ab168b6ae22886fe9ded214430dbb4f41c28cf176da" - [[package]] name = "block-buffer" version = "0.10.4" @@ -286,12 +228,6 @@ dependencies = [ "serde", ] -[[package]] -name = "built" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d17f4d6e4dc36d1a02fbedc2753a096848e7c1b0772f7654eab8e2c927dd53" - [[package]] name = "bumpalo" version = "3.15.4" @@ -336,20 +272,6 @@ name = "cc" version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" -dependencies = [ - "jobserver", - "libc", -] - -[[package]] -name = "cfg-expr" -version = "0.15.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa50868b64a9a6fda9d593ce778849ea8715cd2a3d2cc17ffdb4a2f2f2f1961d" -dependencies = [ - "smallvec", - "target-lexicon", -] [[package]] name = "cfg-if" @@ -1023,35 +945,20 @@ dependencies = [ [[package]] name = "image" -version = "0.25.0" +version = "0.24.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9b4f005360d32e9325029b38ba47ebd7a56f3316df09249368939562d518645" +checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d" dependencies = [ "bytemuck", "byteorder", "color_quant", "exr", "gif", - "image-webp", + "jpeg-decoder", "num-traits", "png", "qoi", - "ravif", - "rayon", - "rgb", "tiff", - "zune-core", - "zune-jpeg", -] - -[[package]] -name = "image-webp" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba6107a25f04af48ceeb4093eebc9b405ee5a1813a0bab5ecf1805d3eabb3337" -dependencies = [ - "byteorder", - "thiserror", ] [[package]] @@ -1060,12 +967,6 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "029d73f573d8e8d63e6d5020011d3255b28c3ba85d6cf870a07184ed23de9284" -[[package]] -name = "imgref" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44feda355f4159a7c757171a77de25daf6411e217b4cabd03bd6650690468126" - [[package]] name = "indexmap" version = "2.2.5" @@ -1102,17 +1003,6 @@ dependencies = [ "libc", ] -[[package]] -name = "interpolate_name" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - [[package]] name = "itertools" version = "0.12.1" @@ -1128,20 +1018,14 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" -[[package]] -name = "jobserver" -version = "0.1.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" -dependencies = [ - "libc", -] - [[package]] name = "jpeg-decoder" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" +dependencies = [ + "rayon", +] [[package]] name = "js-sys" @@ -1199,17 +1083,6 @@ version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" -[[package]] -name = "libfuzzer-sys" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" -dependencies = [ - "arbitrary", - "cc", - "once_cell", -] - [[package]] name = "libredox" version = "0.0.1" @@ -1252,15 +1125,6 @@ version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" -[[package]] -name = "loop9" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" -dependencies = [ - "imgref", -] - [[package]] name = "lru" version = "0.12.3" @@ -1298,16 +1162,6 @@ dependencies = [ "libc", ] -[[package]] -name = "maybe-rayon" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" -dependencies = [ - "cfg-if", - "rayon", -] - [[package]] name = "md-5" version = "0.10.6" @@ -1404,12 +1258,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16cf681a23b4d0a43fc35024c176437f9dcd818db34e0f42ab456a0ee5ad497b" -[[package]] -name = "new_debug_unreachable" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" - [[package]] name = "nom" version = "7.1.3" @@ -1420,12 +1268,6 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "noop_proc_macro" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" - [[package]] name = "notify" version = "6.1.1" @@ -1454,55 +1296,12 @@ dependencies = [ "winapi", ] -[[package]] -name = "num-bigint" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - [[package]] name = "num-conv" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" -[[package]] -name = "num-derive" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", -] - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" -dependencies = [ - "autocfg", - "num-bigint", - "num-integer", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.18" @@ -1690,12 +1489,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - [[package]] name = "proc-macro-error" version = "1.0.4" @@ -1729,25 +1522,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "profiling" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58" -dependencies = [ - "profiling-procmacros", -] - -[[package]] -name = "profiling-procmacros" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd" -dependencies = [ - "quote", - "syn 2.0.52", -] - [[package]] name = "qoi" version = "0.4.1" @@ -1757,12 +1531,6 @@ dependencies = [ "bytemuck", ] -[[package]] -name = "quick-error" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" - [[package]] name = "quick-xml" version = "0.31.0" @@ -1781,36 +1549,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - [[package]] name = "ratatui" version = "0.26.1" @@ -1831,56 +1569,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "rav1e" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9" -dependencies = [ - "arbitrary", - "arg_enum_proc_macro", - "arrayvec", - "av1-grain", - "bitstream-io", - "built", - "cfg-if", - "interpolate_name", - "itertools", - "libc", - "libfuzzer-sys", - "log", - "maybe-rayon", - "new_debug_unreachable", - "noop_proc_macro", - "num-derive", - "num-traits", - "once_cell", - "paste", - "profiling", - "rand", - "rand_chacha", - "simd_helpers", - "system-deps", - "thiserror", - "v_frame", - "wasm-bindgen", -] - -[[package]] -name = "ravif" -version = "0.11.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc13288f5ab39e6d7c9d501759712e6969fcc9734220846fc9ed26cae2cc4234" -dependencies = [ - "avif-serialize", - "imgref", - "loop9", - "quick-error", - "rav1e", - "rayon", - "rgb", -] - [[package]] name = "rayon" version = "1.9.0" @@ -1950,15 +1638,6 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" -[[package]] -name = "rgb" -version = "0.8.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8" -dependencies = [ - "bytemuck", -] - [[package]] name = "rustc-demangle" version = "0.1.23" @@ -2136,15 +1815,6 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" -[[package]] -name = "simd_helpers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" -dependencies = [ - "quote", -] - [[package]] name = "slab" version = "0.4.9" @@ -2272,25 +1942,6 @@ dependencies = [ "walkdir", ] -[[package]] -name = "system-deps" -version = "6.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8e9199467bcbc77c6a13cc6e32a6af21721ab8c96aa0261856c4fda5a4433f0" -dependencies = [ - "cfg-expr", - "heck 0.4.1", - "pkg-config", - "toml", - "version-compare", -] - -[[package]] -name = "target-lexicon" -version = "0.12.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" - [[package]] name = "thiserror" version = "1.0.58" @@ -2640,17 +2291,6 @@ dependencies = [ "log", ] -[[package]] -name = "v_frame" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6f32aaa24bacd11e488aa9ba66369c7cd514885742c9fe08cfe85884db3e92b" -dependencies = [ - "aligned-vec", - "num-traits", - "wasm-bindgen", -] - [[package]] name = "validator" version = "0.17.0" @@ -2699,12 +2339,6 @@ dependencies = [ "time", ] -[[package]] -name = "version-compare" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" - [[package]] name = "version_check" version = "0.9.4" @@ -3223,7 +2857,6 @@ dependencies = [ "regex", "tokio", "tokio-stream", - "tokio-util", "tracing", "trash", "yazi-adaptor", @@ -3271,12 +2904,6 @@ dependencies = [ "syn 2.0.52", ] -[[package]] -name = "zune-core" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" - [[package]] name = "zune-inflate" version = "0.2.54" @@ -3285,12 +2912,3 @@ checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" dependencies = [ "simd-adler32", ] - -[[package]] -name = "zune-jpeg" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec866b44a2a1fd6133d363f073ca1b179f438f99e7e5bfb1e33f7181facfe448" -dependencies = [ - "zune-core", -] diff --git a/yazi-adaptor/Cargo.toml b/yazi-adaptor/Cargo.toml index 69caf1ee..c4ff4062 100644 --- a/yazi-adaptor/Cargo.toml +++ b/yazi-adaptor/Cargo.toml @@ -18,7 +18,7 @@ arc-swap = "1.7.0" base64 = "0.22.0" color_quant = "1.1.0" crossterm = "0.27.0" -image = "0.25.0" +image = "0.24.9" imagesize = "0.12.0" kamadak-exif = "0.5.5" ratatui = "0.26.1" diff --git a/yazi-core/src/manager/commands/tab_close.rs b/yazi-core/src/manager/commands/tab_close.rs index 7ae538fb..01a23672 100644 --- a/yazi-core/src/manager/commands/tab_close.rs +++ b/yazi-core/src/manager/commands/tab_close.rs @@ -25,7 +25,7 @@ impl Tabs { return; } - self.items.remove(opt.idx); + self.items.remove(opt.idx).shutdown(); if opt.idx <= self.idx { self.set_idx(self.absolute(1)); } diff --git a/yazi-core/src/manager/manager.rs b/yazi-core/src/manager/manager.rs index f536185c..b1fea58c 100644 --- a/yazi-core/src/manager/manager.rs +++ b/yazi-core/src/manager/manager.rs @@ -19,10 +19,12 @@ impl Manager { tabs: Tabs::make(), yanked: Default::default(), - watcher: Watcher::start(), + watcher: Watcher::serve(), mimetype: Default::default(), } } + + pub fn shutdown(&mut self) { self.tabs.iter_mut().for_each(|t| t.shutdown()); } } impl Manager { diff --git a/yazi-core/src/manager/watcher.rs b/yazi-core/src/manager/watcher.rs index e712e038..d2f8837f 100644 --- a/yazi-core/src/manager/watcher.rs +++ b/yazi-core/src/manager/watcher.rs @@ -20,7 +20,7 @@ pub struct Watcher { } impl Watcher { - pub(super) fn start() -> Self { + pub(super) fn serve() -> Self { let (tx, rx) = mpsc::unbounded_channel(); let watcher = RecommendedWatcher::new( { diff --git a/yazi-core/src/tab/tab.rs b/yazi-core/src/tab/tab.rs index 0a36c1f4..f8ccf62e 100644 --- a/yazi-core/src/tab/tab.rs +++ b/yazi-core/src/tab/tab.rs @@ -48,6 +48,14 @@ impl From<&Url> for Tab { fn from(url: &Url) -> Self { Self::from(url.clone()) } } +impl Tab { + pub fn shutdown(&mut self) { + if let Some(handle) = self.search.take() { + handle.abort(); + } + } +} + impl Tab { // --- Current pub fn selected_or_hovered(&self) -> Vec<&Url> { diff --git a/yazi-core/src/tasks/tasks.rs b/yazi-core/src/tasks/tasks.rs index 69b01178..2b680d46 100644 --- a/yazi-core/src/tasks/tasks.rs +++ b/yazi-core/src/tasks/tasks.rs @@ -1,6 +1,6 @@ use std::{sync::Arc, time::Duration}; -use tokio::time::sleep; +use tokio::{task::JoinHandle, time::sleep}; use yazi_scheduler::{Scheduler, TaskSummary}; use yazi_shared::{emit, event::Cmd, term::Term, Layer}; @@ -8,6 +8,7 @@ use super::{TasksProgress, TASKS_BORDER, TASKS_PADDING, TASKS_PERCENT}; pub struct Tasks { pub(super) scheduler: Arc, + handle: JoinHandle<()>, pub visible: bool, pub cursor: usize, @@ -16,17 +17,11 @@ pub struct Tasks { } impl Tasks { - pub fn start() -> Self { - let tasks = Self { - scheduler: Arc::new(Scheduler::start()), - visible: false, - cursor: 0, - progress: Default::default(), - summaries: Default::default(), - }; + pub fn serve() -> Self { + let scheduler = Scheduler::serve(); + let ongoing = scheduler.ongoing.clone(); - let ongoing = tasks.scheduler.ongoing.clone(); - tokio::spawn(async move { + let handle = tokio::spawn(async move { let mut last = TasksProgress::default(); loop { sleep(Duration::from_millis(500)).await; @@ -39,7 +34,20 @@ impl Tasks { } }); - tasks + Self { + scheduler: Arc::new(scheduler), + handle, + + visible: false, + cursor: 0, + progress: Default::default(), + summaries: Default::default(), + } + } + + pub fn shutdown(&self) { + self.scheduler.shutdown(); + self.handle.abort(); } #[inline] diff --git a/yazi-fm/src/app/commands/quit.rs b/yazi-fm/src/app/commands/quit.rs index e4bbf4cb..e3d2ac18 100644 --- a/yazi-fm/src/app/commands/quit.rs +++ b/yazi-fm/src/app/commands/quit.rs @@ -7,6 +7,9 @@ use crate::app::App; impl App { pub(crate) fn quit(&mut self, opt: EventQuit) -> ! { + self.cx.tasks.shutdown(); + self.cx.manager.shutdown(); + if !opt.no_cwd_file { self.cwd_to_file(); } diff --git a/yazi-fm/src/context.rs b/yazi-fm/src/context.rs index 30e6c882..3c12b7d5 100644 --- a/yazi-fm/src/context.rs +++ b/yazi-fm/src/context.rs @@ -17,7 +17,7 @@ impl Ctx { pub fn make() -> Self { Self { manager: Manager::make(), - tasks: Tasks::start(), + tasks: Tasks::serve(), select: Default::default(), input: Default::default(), help: Default::default(), diff --git a/yazi-proxy/src/select.rs b/yazi-proxy/src/select.rs index 5629485d..fd00aca9 100644 --- a/yazi-proxy/src/select.rs +++ b/yazi-proxy/src/select.rs @@ -1,6 +1,6 @@ use tokio::sync::oneshot; use yazi_config::popup::SelectCfg; -use yazi_shared::{emit, event::Cmd, term::Term, Layer}; +use yazi_shared::{emit, event::Cmd, Layer}; use crate::options::SelectOpt; @@ -11,6 +11,6 @@ impl SelectProxy { pub async fn show(cfg: SelectCfg) -> anyhow::Result { let (tx, rx) = oneshot::channel(); emit!(Call(Cmd::new("show").with_data(SelectOpt { cfg, tx }), Layer::Select)); - rx.await.unwrap_or_else(|_| Term::goodbye(|| false)) + rx.await? } } diff --git a/yazi-scheduler/Cargo.toml b/yazi-scheduler/Cargo.toml index 6b8a51db..2e5e0524 100644 --- a/yazi-scheduler/Cargo.toml +++ b/yazi-scheduler/Cargo.toml @@ -25,7 +25,6 @@ parking_lot = "0.12.1" regex = "1.10.3" tokio = { version = "1.36.0", features = [ "parking_lot", "rt-multi-thread" ] } tokio-stream = "0.1.15" -tokio-util = "0.7.10" # Logging tracing = { version = "0.1.40", features = [ "max_level_debug", "release_max_level_warn" ] } diff --git a/yazi-scheduler/src/process/op.rs b/yazi-scheduler/src/process/op.rs index b740e071..e00d39a5 100644 --- a/yazi-scheduler/src/process/op.rs +++ b/yazi-scheduler/src/process/op.rs @@ -1,6 +1,6 @@ use std::ffi::OsString; -use tokio_util::sync::CancellationToken; +use tokio::sync::mpsc; use super::ShellOpt; @@ -32,10 +32,10 @@ impl From for ShellOpt { #[derive(Debug)] pub struct ProcessOpBg { - pub id: usize, - pub cmd: OsString, - pub args: Vec, - pub ct: CancellationToken, + pub id: usize, + pub cmd: OsString, + pub args: Vec, + pub cancel: mpsc::Receiver<()>, } impl From for ShellOpt { diff --git a/yazi-scheduler/src/process/process.rs b/yazi-scheduler/src/process/process.rs index e868f3ae..0c2feb0f 100644 --- a/yazi-scheduler/src/process/process.rs +++ b/yazi-scheduler/src/process/process.rs @@ -57,10 +57,12 @@ impl Process { let mut stdout = BufReader::new(child.stdout.take().unwrap()).lines(); let mut stderr = BufReader::new(child.stderr.take().unwrap()).lines(); + let mut cancel = task.cancel; loop { select! { - _ = task.ct.cancelled() => { + _ = cancel.recv() => { child.start_kill().ok(); + cancel.close(); break; } Ok(Some(line)) = stdout.next_line() => { diff --git a/yazi-scheduler/src/scheduler.rs b/yazi-scheduler/src/scheduler.rs index 8cff33eb..8449d92b 100644 --- a/yazi-scheduler/src/scheduler.rs +++ b/yazi-scheduler/src/scheduler.rs @@ -2,8 +2,7 @@ use std::{borrow::Cow, ffi::OsString, sync::Arc, time::Duration}; use futures::{future::BoxFuture, FutureExt}; use parking_lot::Mutex; -use tokio::{fs, select, sync::{mpsc::{self, UnboundedReceiver}, oneshot}}; -use tokio_util::sync::CancellationToken; +use tokio::{fs, select, sync::{mpsc::{self, UnboundedReceiver}, oneshot}, task::JoinHandle}; use yazi_config::{open::Opener, plugin::PluginRule, TASKS}; use yazi_plugin::ValueSendable; use yazi_shared::{fs::{unique_path, Url}, Throttle}; @@ -19,16 +18,17 @@ pub struct Scheduler { micro: async_priority_channel::Sender, u8>, prog: mpsc::UnboundedSender, + handles: Vec>, pub ongoing: Arc>, } impl Scheduler { - pub fn start() -> Self { + pub fn serve() -> Self { let (micro_tx, micro_rx) = async_priority_channel::unbounded(); let (macro_tx, macro_rx) = async_priority_channel::unbounded(); let (prog_tx, prog_rx) = mpsc::unbounded_channel(); - let scheduler = Self { + let mut scheduler = Self { file: Arc::new(File::new(macro_tx.clone(), prog_tx.clone())), plugin: Arc::new(Plugin::new(macro_tx.clone(), prog_tx.clone())), preload: Arc::new(Preload::new(macro_tx.clone(), prog_tx.clone())), @@ -36,132 +36,35 @@ impl Scheduler { micro: micro_tx, prog: prog_tx, + handles: Vec::with_capacity(TASKS.micro_workers as usize + TASKS.macro_workers as usize + 1), ongoing: Default::default(), }; for _ in 0..TASKS.micro_workers { - scheduler.schedule_micro(micro_rx.clone()); + scheduler.handles.push(scheduler.schedule_micro(micro_rx.clone())); } for _ in 0..TASKS.macro_workers { - scheduler.schedule_macro(micro_rx.clone(), macro_rx.clone()); + scheduler.handles.push(scheduler.schedule_macro(micro_rx.clone(), macro_rx.clone())); } scheduler.progress(prog_rx); scheduler } - fn schedule_micro(&self, rx: async_priority_channel::Receiver, u8>) { - tokio::spawn(async move { - loop { - if let Ok((fut, _)) = rx.recv().await { - fut.await; - } - } - }); - } - - fn schedule_macro( - &self, - micro: async_priority_channel::Receiver, u8>, - macro_: async_priority_channel::Receiver, - ) { - let file = self.file.clone(); - let plugin = self.plugin.clone(); - let preload = self.preload.clone(); - - let prog = self.prog.clone(); - let ongoing = self.ongoing.clone(); - - tokio::spawn(async move { - loop { - select! { - Ok((fut, _)) = micro.recv() => { - fut.await; - } - Ok((op, _)) = macro_.recv() => { - let id = op.id(); - if !ongoing.lock().exists(id) { - continue; - } - - let result = match op { - TaskOp::File(op) => file.work(*op).await, - TaskOp::Plugin(op) => plugin.work(*op).await, - TaskOp::Preload(op) => preload.work(*op).await, - }; - - if let Err(e) = result { - prog.send(TaskProg::Fail(id, format!("Failed to work on this task: {:?}", e))).ok(); - } - } - } - } - }); - } - - fn progress(&self, mut rx: UnboundedReceiver) { - let micro = self.micro.clone(); - let ongoing = self.ongoing.clone(); - - tokio::spawn(async move { - while let Some(op) = rx.recv().await { - match op { - TaskProg::New(id, size) => { - if let Some(task) = ongoing.lock().get_mut(id) { - task.total += 1; - task.found += size; - } - } - TaskProg::Adv(id, succ, processed) => { - let mut ongoing = ongoing.lock(); - if let Some(task) = ongoing.get_mut(id) { - task.succ += succ; - task.processed += processed; - } - if succ > 0 { - if let Some(fut) = ongoing.try_remove(id, TaskStage::Pending) { - micro.try_send(fut, NORMAL).ok(); - } - } - } - TaskProg::Succ(id) => { - if let Some(fut) = ongoing.lock().try_remove(id, TaskStage::Dispatched) { - micro.try_send(fut, NORMAL).ok(); - } - } - TaskProg::Fail(id, reason) => { - if let Some(task) = ongoing.lock().get_mut(id) { - task.fail += 1; - task.logs.push_str(&reason); - task.logs.push('\n'); - - if let Some(logger) = &task.logger { - logger.send(reason).ok(); - } - } - } - TaskProg::Log(id, line) => { - if let Some(task) = ongoing.lock().get_mut(id) { - task.logs.push_str(&line); - task.logs.push('\n'); - - if let Some(logger) = &task.logger { - logger.send(line).ok(); - } - } - } - } - } - }); - } - pub fn cancel(&self, id: usize) -> bool { let mut ongoing = self.ongoing.lock(); - let b = ongoing.all.remove(&id).is_some(); if let Some(hook) = ongoing.hooks.remove(&id) { self.micro.try_send(hook(true), HIGH).ok(); + return false; + } + + ongoing.all.remove(&id).is_some() + } + + pub fn shutdown(&self) { + for handle in &self.handles { + handle.abort(); } - b } pub fn file_cut(&self, from: Url, mut to: Url, force: bool) { @@ -285,7 +188,7 @@ impl Scheduler { plugin.micro(PluginOpEntry { id, name, args }).await.ok(); } .boxed(), - HIGH, + NORMAL, ); } @@ -309,7 +212,7 @@ impl Scheduler { preload.rule(PreloadOpRule { id, plugin, targets }).await.ok(); } .boxed(), - HIGH, + NORMAL, ); } @@ -328,7 +231,7 @@ impl Scheduler { preload.size(PreloadOpSize { id, target, throttle }).await.ok(); } .boxed(), - HIGH, + NORMAL, ); } } @@ -348,40 +251,149 @@ impl Scheduler { } }; - let ct = CancellationToken::new(); + let (cancel_tx, cancel_rx) = mpsc::channel(1); let mut ongoing = self.ongoing.lock(); let id = ongoing.add(TaskKind::User, name); ongoing.hooks.insert(id, { - let ct = ct.clone(); let ongoing = self.ongoing.clone(); Box::new(move |canceled: bool| { async move { - ongoing.lock().try_remove(id, TaskStage::Hooked); if canceled { - ct.cancel(); + cancel_tx.send(()).await.ok(); + cancel_tx.closed().await; } if let Some(tx) = done { tx.send(()).ok(); } + ongoing.lock().try_remove(id, TaskStage::Hooked); } .boxed() }) }); + let cmd = OsString::from(&opener.run); let process = self.process.clone(); _ = self.micro.try_send( async move { if opener.block { - process.block(ProcessOpBlock { id, cmd: OsString::from(&opener.run), args }).await.ok(); + process.block(ProcessOpBlock { id, cmd, args }).await.ok(); } else if opener.orphan { - process.orphan(ProcessOpOrphan { id, cmd: OsString::from(&opener.run), args }).await.ok(); + process.orphan(ProcessOpOrphan { id, cmd, args }).await.ok(); } else { - process.bg(ProcessOpBg { id, cmd: OsString::from(&opener.run), args, ct }).await.ok(); + process.bg(ProcessOpBg { id, cmd, args, cancel: cancel_rx }).await.ok(); } } .boxed(), - HIGH, + NORMAL, ); } + + fn schedule_micro( + &self, + rx: async_priority_channel::Receiver, u8>, + ) -> JoinHandle<()> { + tokio::spawn(async move { + loop { + if let Ok((fut, _)) = rx.recv().await { + fut.await; + } + } + }) + } + + fn schedule_macro( + &self, + micro: async_priority_channel::Receiver, u8>, + macro_: async_priority_channel::Receiver, + ) -> JoinHandle<()> { + let file = self.file.clone(); + let plugin = self.plugin.clone(); + let preload = self.preload.clone(); + + let prog = self.prog.clone(); + let ongoing = self.ongoing.clone(); + + tokio::spawn(async move { + loop { + select! { + Ok((fut, _)) = micro.recv() => { + fut.await; + } + Ok((op, _)) = macro_.recv() => { + let id = op.id(); + if !ongoing.lock().exists(id) { + continue; + } + + let result = match op { + TaskOp::File(op) => file.work(*op).await, + TaskOp::Plugin(op) => plugin.work(*op).await, + TaskOp::Preload(op) => preload.work(*op).await, + }; + + if let Err(e) = result { + prog.send(TaskProg::Fail(id, format!("Failed to work on this task: {:?}", e))).ok(); + } + } + } + } + }) + } + + fn progress(&self, mut rx: UnboundedReceiver) -> JoinHandle<()> { + let micro = self.micro.clone(); + let ongoing = self.ongoing.clone(); + + tokio::spawn(async move { + while let Some(op) = rx.recv().await { + match op { + TaskProg::New(id, size) => { + if let Some(task) = ongoing.lock().get_mut(id) { + task.total += 1; + task.found += size; + } + } + TaskProg::Adv(id, succ, processed) => { + let mut ongoing = ongoing.lock(); + if let Some(task) = ongoing.get_mut(id) { + task.succ += succ; + task.processed += processed; + } + if succ > 0 { + if let Some(fut) = ongoing.try_remove(id, TaskStage::Pending) { + micro.try_send(fut, LOW).ok(); + } + } + } + TaskProg::Succ(id) => { + if let Some(fut) = ongoing.lock().try_remove(id, TaskStage::Dispatched) { + micro.try_send(fut, LOW).ok(); + } + } + TaskProg::Fail(id, reason) => { + if let Some(task) = ongoing.lock().get_mut(id) { + task.fail += 1; + task.logs.push_str(&reason); + task.logs.push('\n'); + + if let Some(logger) = &task.logger { + logger.send(reason).ok(); + } + } + } + TaskProg::Log(id, line) => { + if let Some(task) = ongoing.lock().get_mut(id) { + task.logs.push_str(&line); + task.logs.push('\n'); + + if let Some(logger) = &task.logger { + logger.send(line).ok(); + } + } + } + } + } + }) + } } diff --git a/yazi-shared/src/event/event.rs b/yazi-shared/src/event/event.rs index 19006883..808d7a0d 100644 --- a/yazi-shared/src/event/event.rs +++ b/yazi-shared/src/event/event.rs @@ -1,10 +1,10 @@ use std::{collections::VecDeque, ffi::OsString}; use crossterm::event::KeyEvent; -use tokio::sync::{mpsc, oneshot}; +use tokio::sync::mpsc; use super::Cmd; -use crate::{term::Term, Layer, RoCell}; +use crate::{Layer, RoCell}; static TX: RoCell> = RoCell::new(); @@ -31,12 +31,6 @@ impl Event { #[inline] pub fn emit(self) { TX.send(self).ok(); } - - #[inline] - pub async fn wait(self, rx: oneshot::Receiver) -> T { - TX.send(self).ok(); - rx.await.unwrap_or_else(|_| Term::goodbye(|| false)) - } } #[macro_export]