1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
//!
//! # Rust Threadpool Executor
//!
//! A simple thread pool for running jobs on the worker threads. You can specify the core workers which will live as long as the thread pool , maximum workers which will live with a given keep alive time, and the policy when the jobs submited exceed the maximum size of the workers.
//!
//! ## Usage
//!
//! Create a fix size thread pool and when the job submited will wait when all workers are busy:
//!
//! ```rust
//!
//! let pool = threadpool_executor::ThreadPool::new(1);
//! let mut expectation = pool.execute(|| {"hello, thread pool!"}).unwrap();
//! assert_eq!(expectation.get_result().unwrap(), "hello, thread pool!");
//! ```
//!
//! You can handle wait the result for a specifid time:
//!
//! ```rust
//! let pool = threadpool_executor::ThreadPool::new(1);
//! let r = pool.execute(|| {
//! std::thread::sleep(std::time::Duration::from_secs(10));
//! });
//! let res = r.unwrap().get_result_timeout(std::time::Duration::from_secs(3));
//! assert!(res.is_err());
//! if let Err(err) = res {
//! matches!(err.kind(), threadpool_executor::error::ErrorKind::TimeOut);
//! }
//! ```
//!
//! Use `Builder` to create a thread pool:
//!
//! ```rust
//! let pool = threadpool_executor::threadpool::Builder::new()
//! .core_pool_size(1)
//! .maximum_pool_size(3)
//! .keep_alive_time(std::time::Duration::from_secs(300))
//! .exeed_limit_policy(threadpool_executor::threadpool::ExceedLimitPolicy::Wait)
//! .build();
//! ```
//!
//! The workers runs in this thread pool will try to catch the `Panic!` using the `std::panic::catch_unwind` in the functions you submit, if catched, the `get_result` method will give you a `Panic` kind ExecutorError.
//!
//! ```rust
//! let pool = threadpool_executor::ThreadPool::new(1);
//! let r = pool.execute(|| {
//! panic!("panic!!!");
//! });
//! let res = r.unwrap().get_result();
//! assert!(res.is_err());
//! if let Err(err) = res {
//! matches!(err.kind(), threadpool_executor::error::ErrorKind::Panic);
//! }
//! ```
use crossbeam_channel::{Receiver, Sender};
use std::{
any::Any,
collections::HashMap,
sync::{atomic::AtomicUsize, Arc, Mutex},
thread,
time::Duration,
};
pub mod error;
pub mod threadpool;
pub struct Expectation<T> {
result_receiver: Option<Receiver<Result<T, Box<dyn Any + Send>>>>,
}
pub struct ThreadPool {
current_id: AtomicUsize,
workers: Arc<Mutex<HashMap<usize, threadpool::Worker>>>,
worker_count: Arc<AtomicUsize>,
working_count: Arc<AtomicUsize>,
task_sender: Option<Sender<threadpool::Job>>,
task_receiver: Receiver<threadpool::Job>,
worker_status_sender: Option<Sender<(usize, threadpool::WorkerStatus)>>,
m_thread: Option<thread::JoinHandle<()>>,
max_size: usize,
policy: threadpool::ExceedLimitPolicy,
keep_alive_time: Option<Duration>,
}