diff --git a/src/main.rs b/src/main.rs index 10ead08..3f1f7dd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,11 +11,15 @@ pub mod utils; use std::{env, path::PathBuf}; use cli::CliArgs; -use error::{Error, Result}; use once_cell::sync::Lazy; -use utils::{QuestionAction, QuestionPolicy}; -use crate::utils::logger::spawn_logger_thread; +use self::{ + error::{Error, Result}, + utils::{ + logger::{shutdown_logger_and_wait, spawn_logger_thread}, + QuestionAction, QuestionPolicy, + }, +}; // Used in BufReader and BufWriter to perform less syscalls const BUFFER_CAPACITY: usize = 1024 * 32; @@ -27,9 +31,9 @@ static CURRENT_DIRECTORY: Lazy = Lazy::new(|| env::current_dir().unwrap pub const EXIT_FAILURE: i32 = libc::EXIT_FAILURE; fn main() { - let handler = spawn_logger_thread(); + spawn_logger_thread(); let result = run(); - handler.shutdown_and_wait(); + shutdown_logger_and_wait(); if let Err(err) = result { eprintln!("{err}"); diff --git a/src/utils/logger.rs b/src/utils/logger.rs index 4f0bf53..5156308 100644 --- a/src/utils/logger.rs +++ b/src/utils/logger.rs @@ -5,10 +5,16 @@ pub use logger_thread::spawn_logger_thread; use super::colors::{ORANGE, RESET, YELLOW}; use crate::accessible::is_running_in_accessible_mode; +/// Asks logger to shutdown and waits till it flushes all pending messages. +#[track_caller] +pub fn shutdown_logger_and_wait() { + logger_thread::send_shutdown_command_and_wait(); +} + /// Asks logger to flush all messages, useful before starting STDIN interaction. #[track_caller] pub fn flush_messages() { - logger_thread::send_flush_message_and_wait(); + logger_thread::send_flush_command_and_wait(); } /// An `[INFO]` log to be displayed if we're not running accessibility mode. @@ -36,7 +42,7 @@ pub fn info_accessible(contents: String) { #[track_caller] fn info_with_accessibility(contents: String, accessible: bool) { - logger_thread::send_log_message(PrintMessage { + logger_thread::send_print_command(PrintMessage { contents, accessible, level: MessageLevel::Info, @@ -45,7 +51,7 @@ fn info_with_accessibility(contents: String, accessible: bool) { #[track_caller] pub fn warning(contents: String) { - logger_thread::send_log_message(PrintMessage { + logger_thread::send_print_command(PrintMessage { contents, // Warnings are important and unlikely to flood, so they should be displayed accessible: true, @@ -57,7 +63,7 @@ pub fn warning(contents: String) { enum LoggerCommand { Print(PrintMessage), Flush { finished_barrier: Arc }, - FlushAndShutdown, + FlushAndShutdown { finished_barrier: Arc }, } /// Message object used for sending logs from worker threads to a logging thread via channels. @@ -70,7 +76,7 @@ struct PrintMessage { } impl PrintMessage { - fn to_processed_message(&self) -> Option { + fn to_formatted_message(&self) -> Option { match self.level { MessageLevel::Info => { if self.accessible { @@ -128,71 +134,44 @@ mod logger_thread { } #[track_caller] - pub(super) fn send_log_message(msg: PrintMessage) { + pub(super) fn send_print_command(msg: PrintMessage) { get_sender() .send(LoggerCommand::Print(msg)) - .expect("Failed to send print message"); + .expect("Failed to send print command"); } #[track_caller] - fn send_shutdown_message() { - get_sender() - .send(LoggerCommand::FlushAndShutdown) - .expect("Failed to send shutdown message"); - } - - #[track_caller] - pub(super) fn send_flush_message_and_wait() { + pub(super) fn send_flush_command_and_wait() { let barrier = Arc::new(Barrier::new(2)); get_sender() .send(LoggerCommand::Flush { finished_barrier: barrier.clone(), }) - .expect("Failed to send shutdown message"); + .expect("Failed to send flush command"); barrier.wait(); } - pub struct LoggerThreadHandle { - shutdown_barrier: Arc, + #[track_caller] + pub(super) fn send_shutdown_command_and_wait() { + let barrier = Arc::new(Barrier::new(2)); + + get_sender() + .send(LoggerCommand::FlushAndShutdown { + finished_barrier: barrier.clone(), + }) + .expect("Failed to send shutdown command"); + + barrier.wait(); } - impl LoggerThreadHandle { - /// Tell logger to shutdown and waits till it does. - pub fn shutdown_and_wait(self) { - // Signal the shutdown - send_shutdown_message(); - // Wait for confirmation - self.shutdown_barrier.wait(); - } - } - - #[cfg(test)] - // shutdown_and_wait must be called manually, but to keep 'em clean, in - // case of tests just do it on drop - impl Drop for LoggerThreadHandle { - fn drop(&mut self) { - send_shutdown_message(); - self.shutdown_barrier.wait(); - } - } - - pub fn spawn_logger_thread() -> LoggerThreadHandle { + pub fn spawn_logger_thread() { let log_receiver = setup_channel(); - - let shutdown_barrier = Arc::new(Barrier::new(2)); - - let handle = LoggerThreadHandle { - shutdown_barrier: shutdown_barrier.clone(), - }; - - rayon::spawn(move || run_logger(log_receiver, shutdown_barrier)); - - handle + rayon::spawn(move || run_logger(log_receiver)); } - fn run_logger(log_receiver: LogReceiver, shutdown_barrier: Arc) { + fn run_logger(log_receiver: LogReceiver) { const FLUSH_TIMEOUT: Duration = Duration::from_millis(200); let mut buffer = Vec::::with_capacity(16); @@ -210,7 +189,7 @@ mod logger_thread { match msg { LoggerCommand::Print(msg) => { // Append message to buffer - if let Some(msg) = msg.to_processed_message() { + if let Some(msg) = msg.to_formatted_message() { buffer.push(msg); } @@ -222,14 +201,13 @@ mod logger_thread { flush_logs_to_stderr(&mut buffer); finished_barrier.wait(); } - LoggerCommand::FlushAndShutdown => { + LoggerCommand::FlushAndShutdown { finished_barrier } => { flush_logs_to_stderr(&mut buffer); - break; + finished_barrier.wait(); + return; } } } - - shutdown_barrier.wait(); } fn flush_logs_to_stderr(buffer: &mut Vec) { diff --git a/tests/snapshots/ui__ui_test_ok_compress-2.snap b/tests/snapshots/ui__ui_test_ok_compress-2.snap index da6dd20..ed872d7 100644 --- a/tests/snapshots/ui__ui_test_ok_compress-2.snap +++ b/tests/snapshots/ui__ui_test_ok_compress-2.snap @@ -2,4 +2,4 @@ source: tests/ui.rs expression: "run_ouch(\"ouch compress input output.gz\", dir)" --- -[INFO] Successfully compressed 'output.gz'. +[INFO] Successfully compressed 'output.gz' diff --git a/tests/snapshots/ui__ui_test_ok_compress.snap b/tests/snapshots/ui__ui_test_ok_compress.snap index 93f1165..2e2aea8 100644 --- a/tests/snapshots/ui__ui_test_ok_compress.snap +++ b/tests/snapshots/ui__ui_test_ok_compress.snap @@ -2,5 +2,5 @@ source: tests/ui.rs expression: "run_ouch(\"ouch compress input output.zip\", dir)" --- -[INFO] Compressing 'input'. -[INFO] Successfully compressed 'output.zip'. +[INFO] Compressing 'input' +[INFO] Successfully compressed 'output.zip' diff --git a/tests/snapshots/ui__ui_test_ok_decompress.snap b/tests/snapshots/ui__ui_test_ok_decompress.snap index a226ed3..73d8678 100644 --- a/tests/snapshots/ui__ui_test_ok_decompress.snap +++ b/tests/snapshots/ui__ui_test_ok_decompress.snap @@ -2,5 +2,5 @@ source: tests/ui.rs expression: "run_ouch(\"ouch decompress output.zst\", dir)" --- -[INFO] Successfully decompressed archive in current directory. +[INFO] Successfully decompressed archive in current directory [INFO] Files unpacked: 1 diff --git a/tests/snapshots/ui__ui_test_ok_format_flag_with_rar-1.snap b/tests/snapshots/ui__ui_test_ok_format_flag_with_rar-1.snap index e48f9a1..ba8bb9e 100644 --- a/tests/snapshots/ui__ui_test_ok_format_flag_with_rar-1.snap +++ b/tests/snapshots/ui__ui_test_ok_format_flag_with_rar-1.snap @@ -2,5 +2,5 @@ source: tests/ui.rs expression: "run_ouch(\"ouch compress input output1 --format tar.gz\", dir)" --- -[INFO] Compressing 'input'. -[INFO] Successfully compressed 'output1'. +[INFO] Compressing 'input' +[INFO] Successfully compressed 'output1' diff --git a/tests/snapshots/ui__ui_test_ok_format_flag_with_rar-2.snap b/tests/snapshots/ui__ui_test_ok_format_flag_with_rar-2.snap index aab5ab2..ccaf1dd 100644 --- a/tests/snapshots/ui__ui_test_ok_format_flag_with_rar-2.snap +++ b/tests/snapshots/ui__ui_test_ok_format_flag_with_rar-2.snap @@ -2,5 +2,5 @@ source: tests/ui.rs expression: "run_ouch(\"ouch compress input output2 --format .tar.gz\", dir)" --- -[INFO] Compressing 'input'. -[INFO] Successfully compressed 'output2'. +[INFO] Compressing 'input' +[INFO] Successfully compressed 'output2' diff --git a/tests/snapshots/ui__ui_test_ok_format_flag_without_rar-1.snap b/tests/snapshots/ui__ui_test_ok_format_flag_without_rar-1.snap index e48f9a1..ba8bb9e 100644 --- a/tests/snapshots/ui__ui_test_ok_format_flag_without_rar-1.snap +++ b/tests/snapshots/ui__ui_test_ok_format_flag_without_rar-1.snap @@ -2,5 +2,5 @@ source: tests/ui.rs expression: "run_ouch(\"ouch compress input output1 --format tar.gz\", dir)" --- -[INFO] Compressing 'input'. -[INFO] Successfully compressed 'output1'. +[INFO] Compressing 'input' +[INFO] Successfully compressed 'output1' diff --git a/tests/snapshots/ui__ui_test_ok_format_flag_without_rar-2.snap b/tests/snapshots/ui__ui_test_ok_format_flag_without_rar-2.snap index aab5ab2..ccaf1dd 100644 --- a/tests/snapshots/ui__ui_test_ok_format_flag_without_rar-2.snap +++ b/tests/snapshots/ui__ui_test_ok_format_flag_without_rar-2.snap @@ -2,5 +2,5 @@ source: tests/ui.rs expression: "run_ouch(\"ouch compress input output2 --format .tar.gz\", dir)" --- -[INFO] Compressing 'input'. -[INFO] Successfully compressed 'output2'. +[INFO] Compressing 'input' +[INFO] Successfully compressed 'output2'