parallel_worker/
lib.rs

1//! # Parallel Worker
2//!
3//! This crate provides a simple interface for running tasks in parallel.
4//! The Worker structs are used to dispatch tasks to worker threads and collect the results.
5//! You can wait for results or receive currently available results.
6//!
7//! ## Workers
8//! There are three types of workers:
9//! - [`BasicWorker`] is a simple worker that processes tasks in parallel using multiple worker threads.
10//! - [`CancelableWorker`] has additional functionality for optional results and task cancellation during execution.
11//! - [`OrderedWorker`] returns results in the same order as the tasks were added.
12//!
13//! ## Example
14//! Basic example of using a worker to run tasks in parallel using the [`BasicWorker`] struct.
15//! Tasks start executing as soon as they are added. When all threads are busy, tasks are queued until a thread becomes available.
16//! ```rust
17//!  use parallel_worker::prelude::*;
18//!
19//!  fn main() {
20//!     let mut worker = BasicWorker::new(|n| {
21//!        // Answer to life, the universe and everything
22//!        return 42;
23//!     });
24//!
25//!     worker.add_task(1);
26//!     worker.add_task(2);
27//!
28//!     assert_eq!(worker.get_blocking(), Some(42));
29//!     
30//!     worker.add_tasks(0..10);
31//!
32//!     assert_eq!(worker.get_iter_blocking().count(), 11);
33//! }
34//! ```
35//!
36//! ## Tasks can be canceled
37//! If you want to cancel tasks during execution, use [`CancelableWorker`] and call the [`check_if_cancelled!`]
38//! macro in your worker function on a regular basis. Excessive checking will lead to a performance costs.
39//! Canceled tasks will stop executing as soon as they reach a [`check_if_cancelled!`].
40//! Results of canceled tasks will be discarded.
41//! Results of tasks that have already completed will remain unaffected.  
42//! ```rust
43//! use parallel_worker::prelude::*;
44//!
45//! # use std::{thread::sleep, time::Duration};
46//! fn main() {
47//!     let mut worker = CancelableWorker::new(worker_function);
48//!
49//!     worker.add_tasks([1, 2, 3, 4]);
50//!
51//!     worker.cancel_tasks();
52//!
53//!     assert!(worker.get_blocking().is_none());
54//! }
55//!
56//! fn worker_function(task: u64, state: &State) -> Option<u64> {
57//!     loop {
58//!         sleep(Duration::from_millis(50));
59//!         check_if_cancelled!(state);
60//!     }
61//!     unreachable!()
62//! }
63//!```
64//! ## Results can be optional
65//! If a worker returns [`None`] the result will be discarded. This feature is available in the [`CancelableWorker`].
66//! ```rust
67//! use parallel_worker::prelude::*;
68//!
69//! fn main() {
70//!     let mut worker = CancelableWorker::new(|n: u64, _s: &State| {
71//!         if n % 2 == 0 {
72//!             Some(n)
73//!         } else {
74//!             None
75//!         }
76//!     });
77//!     
78//!     worker.add_tasks(1..=10);
79//!
80//!     assert_eq!(worker.get_iter_blocking().count(), 5);
81//! }
82//! ```
83//!
84//! ## Results can be ordered
85//! If you want to get results in the same order as the tasks were added, use [`OrderedWorker`].
86//! ```rust
87//! use parallel_worker::prelude::*;
88//! # use std::{thread::sleep, time::Duration};
89//!
90//! fn main() {
91//!     let mut worker = OrderedWorker::new(|n: u64| {
92//!         sleep(std::time::Duration::from_millis(n % 3));
93//!         n    
94//!     });
95//!
96//!     worker.add_task(1);
97//!     worker.add_task(2);
98//!     worker.add_tasks(3..=10);
99//!
100//!     assert_eq!(worker.get_vec_blocking(), (1..=10).collect::<Vec<_>>());
101//! }
102//! ```
103
104mod internal;
105pub use internal::State;
106
107mod worker_traits;
108pub use worker_traits::{WorkerInit, WorkerMethods};
109
110mod workers;
111    pub use workers::{BasicWorker, CancelableWorker, OrderedWorker};
112
113pub mod prelude {
114    pub use crate::check_if_cancelled;
115    pub use crate::internal::State;
116    pub use crate::worker_traits::{WorkerInit, WorkerMethods};
117    pub use crate::workers::{
118        BasicWorker, CancelableWorker, OrderedWorker,
119    };
120}