Wire thread count and error behavior settings into executor

The PipelineExecutor now stores thread_count and pause_on_error
fields. When pause_on_error is enabled, the executor sets the
pause flag on failures so the user can review errors. The GUI
reads these settings from AppConfig before starting processing.
This commit is contained in:
2026-03-06 13:52:08 +02:00
parent be081307c4
commit abd794b3b9
2 changed files with 34 additions and 1 deletions

View File

@@ -33,6 +33,8 @@ pub struct BatchResult {
pub struct PipelineExecutor { pub struct PipelineExecutor {
cancel_flag: Arc<AtomicBool>, cancel_flag: Arc<AtomicBool>,
pause_flag: Arc<AtomicBool>, pause_flag: Arc<AtomicBool>,
thread_count: usize,
pause_on_error: bool,
} }
impl PipelineExecutor { impl PipelineExecutor {
@@ -40,6 +42,8 @@ impl PipelineExecutor {
Self { Self {
cancel_flag: Arc::new(AtomicBool::new(false)), cancel_flag: Arc::new(AtomicBool::new(false)),
pause_flag: Arc::new(AtomicBool::new(false)), pause_flag: Arc::new(AtomicBool::new(false)),
thread_count: num_cpus(),
pause_on_error: false,
} }
} }
@@ -47,6 +51,8 @@ impl PipelineExecutor {
Self { Self {
cancel_flag, cancel_flag,
pause_flag: Arc::new(AtomicBool::new(false)), pause_flag: Arc::new(AtomicBool::new(false)),
thread_count: num_cpus(),
pause_on_error: false,
} }
} }
@@ -57,9 +63,19 @@ impl PipelineExecutor {
Self { Self {
cancel_flag, cancel_flag,
pause_flag, pause_flag,
thread_count: num_cpus(),
pause_on_error: false,
} }
} }
pub fn set_thread_count(&mut self, count: usize) {
self.thread_count = if count == 0 { num_cpus() } else { count };
}
pub fn set_pause_on_error(&mut self, pause: bool) {
self.pause_on_error = pause;
}
pub fn execute<F>(&self, job: &ProcessingJob, mut on_progress: F) -> Result<BatchResult> pub fn execute<F>(&self, job: &ProcessingJob, mut on_progress: F) -> Result<BatchResult>
where where
F: FnMut(ProgressUpdate) + Send, F: FnMut(ProgressUpdate) + Send,
@@ -122,6 +138,9 @@ impl PipelineExecutor {
Err(e) => { Err(e) => {
result.failed += 1; result.failed += 1;
result.errors.push((file_name, e.to_string())); result.errors.push((file_name, e.to_string()));
if self.pause_on_error {
self.pause_flag.store(true, Ordering::Relaxed);
}
} }
} }
} }
@@ -198,3 +217,9 @@ impl Default for PipelineExecutor {
Self::new() Self::new()
} }
} }
fn num_cpus() -> usize {
std::thread::available_parallelism()
.map(|n| n.get())
.unwrap_or(1)
}

View File

@@ -1219,8 +1219,16 @@ fn run_processing(_window: &adw::ApplicationWindow, ui: &WizardUi) {
let cancel = cancel_flag.clone(); let cancel = cancel_flag.clone();
let pause = pause_flag.clone(); let pause = pause_flag.clone();
// Load processing settings from config
let cfg_store = pixstrip_core::storage::ConfigStore::new();
let app_cfg = cfg_store.load().unwrap_or_default();
std::thread::spawn(move || { std::thread::spawn(move || {
let executor = pixstrip_core::executor::PipelineExecutor::with_cancel_and_pause(cancel, pause); let mut executor = pixstrip_core::executor::PipelineExecutor::with_cancel_and_pause(cancel, pause);
match app_cfg.thread_count {
pixstrip_core::config::ThreadCount::Auto => executor.set_thread_count(0),
pixstrip_core::config::ThreadCount::Manual(n) => executor.set_thread_count(n),
}
executor.set_pause_on_error(app_cfg.error_behavior == pixstrip_core::config::ErrorBehavior::PauseOnError);
let result = executor.execute(&job, |update| { let result = executor.execute(&job, |update| {
let _ = tx.send(ProcessingMessage::Progress { let _ = tx.send(ProcessingMessage::Progress {
current: update.current, current: update.current,