fd/src/exec/job.rs

67 lines
2.2 KiB
Rust
Raw Normal View History

2018-04-13 22:46:17 +02:00
use std::sync::{Arc, Mutex};
2017-10-14 18:04:11 +02:00
use crossbeam_channel::Receiver;
use crate::config::Config;
2021-11-30 08:51:16 +01:00
use crate::dir_entry::DirEntry;
2020-04-03 21:18:54 +02:00
use crate::error::print_error;
use crate::exit_codes::{merge_exitcodes, ExitCode};
use crate::walk::WorkerResult;
use super::CommandSet;
2020-04-03 21:18:54 +02:00
2017-10-14 18:04:11 +02:00
/// An event loop that listens for inputs from the `rx` receiver. Each received input will
/// generate a command with the supplied command template. The generated command will then
/// be executed, and this process will continue until the receiver's sender has closed.
2018-09-30 22:56:32 +02:00
pub fn job(
rx: Receiver<WorkerResult>,
cmd: Arc<CommandSet>,
2018-09-30 22:56:32 +02:00
out_perm: Arc<Mutex<()>>,
config: &Config,
) -> ExitCode {
// Output should be buffered when only running a single thread
let buffer_output: bool = config.threads > 1;
let mut results: Vec<ExitCode> = Vec::new();
2017-10-14 18:04:11 +02:00
loop {
2018-10-01 21:29:54 +02:00
// Obtain the next result from the receiver, else if the channel
2017-10-14 18:04:11 +02:00
// has closed, exit from the loop
let dir_entry: DirEntry = match rx.recv() {
Ok(WorkerResult::Entry(dir_entry)) => dir_entry,
2018-10-01 21:29:54 +02:00
Ok(WorkerResult::Error(err)) => {
if config.show_filesystem_errors {
2020-04-03 21:18:54 +02:00
print_error(err.to_string());
2018-10-22 14:20:08 +02:00
}
2018-10-01 21:29:54 +02:00
continue;
}
2017-10-14 20:04:04 +02:00
Err(_) => break,
2017-10-14 18:04:11 +02:00
};
2020-01-26 14:06:18 +01:00
// Generate a command, execute it and store its exit code.
results.push(cmd.execute(
dir_entry.stripped_path(config),
config.path_separator.as_deref(),
Arc::clone(&out_perm),
buffer_output,
))
2017-10-14 18:04:11 +02:00
}
// Returns error in case of any error.
merge_exitcodes(results)
2017-10-14 20:04:04 +02:00
}
pub fn batch(rx: Receiver<WorkerResult>, cmd: &CommandSet, config: &Config) -> ExitCode {
let paths = rx
.into_iter()
.filter_map(|worker_result| match worker_result {
WorkerResult::Entry(dir_entry) => Some(dir_entry.into_stripped_path(config)),
WorkerResult::Error(err) => {
if config.show_filesystem_errors {
print_error(err.to_string());
}
None
}
});
2021-10-22 08:05:13 +02:00
cmd.execute_batch(paths, config.batch_size, config.path_separator.as_deref())
}