pub struct WorkerPool<Up, Down>{ /* private fields */ }Expand description
The main struct, represents a pool of worker. The owner of this struct is the “Manager”, while the threads handled by this struct are the “Workers”.
§Example
use worker_pool::WorkerPool;
let mut pool: WorkerPool<String, ()> = WorkerPool::new(100);
pool.execute(|tx, _rx| {
tx.send(String::from("Hello"));
tx.send(String::from("world!"));
});
assert_eq!(pool.stop().collect::<Vec<_>>().join(" "), "Hello world!");Implementations§
Source§impl<Up, Down> WorkerPool<Up, Down>
impl<Up, Down> WorkerPool<Up, Down>
Sourcepub fn new(buffer_length: usize) -> Self
pub fn new(buffer_length: usize) -> Self
Creates a new WorkerPool instance, with a given maximum buffer length.
The higher the buffer length, the higher the message throughput, but the higher the memory cost. See SyncSender for more information.
§Example
use std::time::Duration;
use worker_pool::{WorkerPool, DownMsg};
let mut pool: WorkerPool<usize, String> = WorkerPool::new(3);
pool.execute(|tx, rx| {
loop {
let msg = worker_pool::recv_break!(rx);
tx.send(msg.len()).unwrap();
}
});
pool.broadcast(DownMsg::Other(String::from("Betelgeuse")));
pool.broadcast(DownMsg::Other(String::from("Alpha Centauri")));
pool.broadcast(DownMsg::Other(String::from("Sirius")));
// When the worker will send the result for this message, tx.send will block, but the message
// will still count as being sent before recv_burst(). Whether or not it will appear in the
// iterator depends on the speed at which the items in the iterator are read.
pool.broadcast(DownMsg::Other(String::from("Procyon")));
pool.broadcast(DownMsg::Other(String::from("Sun")));
std::thread::sleep(Duration::new(0, 100_000_000));
assert_eq!(
pool.recv_burst().take(3).collect::<Vec<_>>(),
vec![10, 14, 6]
);Sourcepub fn execute<F>(&mut self, callback: F)
pub fn execute<F>(&mut self, callback: F)
Spawns one worker thread with the given callback:
// Spawns 1 worker thread
pool.execute(|tx, rx| {
// Send messages in tx
// Receive messages in rx
});To prevent any deadlocks, the worker thread must stop shortly after receiving the Stop message:
- if it is in an infinite loop, then that loop must be broken (
recv_break!andtry_recv_break!will handle that for you) - after the
Stopmessage is received, it may only wait for space in the buffer oftx - make sure that no lock will prevent a
Stopmessage from being received - the worker thread may
panic!, in which case its exception will be propagated up bystop()andstop_and_join()
Sourcepub fn execute_many<F>(&mut self, n_workers: usize, callback: F)
pub fn execute_many<F>(&mut self, n_workers: usize, callback: F)
Spawns n worker threads with the given callback.
The callback must implement Clone.
// Spawns 16 worker thread
pool.execute_many(16, |tx, rx| {
// Send messages in tx
// Receive messages in rx
});To prevent any deadlocks, the worker threads must stop shortly after receiving the Stop message.
See execute for more information.
Sourcepub fn buffer_length(&self) -> usize
pub fn buffer_length(&self) -> usize
Returns the maximum length of the message queue
Sourcepub fn recv(&mut self) -> Result<Up, RecvError>
pub fn recv(&mut self) -> Result<Up, RecvError>
Receives a single message from a worker; this is a blocking operation.
If you need to call this function repeatedly, then consider iterating over the result of recv_burst instead.
Sourcepub fn recv_burst<'b>(&'b mut self) -> RecvBurstIterator<'b, Up> ⓘ
pub fn recv_burst<'b>(&'b mut self) -> RecvBurstIterator<'b, Up> ⓘ
Returns an iterator that will yield a “burst” of messages. This iterator will respect causality, meaning that it will not yield any message that were sent after it was created. You can thus safely iterate over all of the elements of this iterator without risking a livelock.
Sourcepub fn stop(&mut self) -> RecvAllIterator<Up> ⓘ
pub fn stop(&mut self) -> RecvAllIterator<Up> ⓘ
Stops the execution of all threads, returning an iterator that will yield and join all of the messages from the workers. As soon as this function returns, the WorkerPool will be back to its starting state, allowing you to execute more tasks immediately.
The returned iterator will read all of the remaining messages one by one. Once the last message is received, it will join all threads.
Sourcepub fn stop_and_join(&mut self) -> Vec<Up>
pub fn stop_and_join(&mut self) -> Vec<Up>
Stops the execution of all threads and joins them. Returns a Vec containing all of the remaining yielded values.
Note that the returned Vec will ignore the buffer_length limitation.
Sourcepub fn broadcast(&self, msg: DownMsg<Down>)where
Down: Clone,
pub fn broadcast(&self, msg: DownMsg<Down>)where
Down: Clone,
Sends msg to every worker.
If a worker has dropped their Receiver, then it will be skipped.
Sourcepub fn broadcast_one(
&mut self,
msg: DownMsg<Down>,
) -> Result<(), SendError<DownMsg<Down>>>
pub fn broadcast_one( &mut self, msg: DownMsg<Down>, ) -> Result<(), SendError<DownMsg<Down>>>
Sends msg to a single worker, in a round-robin fashion.
Returns Err if there is no worker or if the worker has dropped its receiver.