WorkerPool

Struct WorkerPool 

Source
pub struct WorkerPool<Up, Down>
where Up: Send + 'static, Down: Send + 'static,
{ /* 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>
where Up: Send + 'static, Down: Send + 'static,

Source

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]
);
Source

pub fn execute<F>(&mut self, callback: F)
where F: FnOnce(WorkerSender<Up>, Receiver<DownMsg<Down>>) + Send + 'static,

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! and try_recv_break! will handle that for you)
  • after the Stop message is received, it may only wait for space in the buffer of tx
  • make sure that no lock will prevent a Stop message from being received
  • the worker thread may panic!, in which case its exception will be propagated up by stop() and stop_and_join()
Source

pub fn execute_many<F>(&mut self, n_workers: usize, callback: F)
where F: FnOnce(WorkerSender<Up>, Receiver<DownMsg<Down>>) + Clone + Send + 'static,

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.

Source

pub fn buffer_length(&self) -> usize

Returns the maximum length of the message queue

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn get( &self, index: usize, ) -> Option<(&JoinHandle<()>, Sender<DownMsg<Down>>)>

Auto Trait Implementations§

§

impl<Up, Down> Freeze for WorkerPool<Up, Down>
where Up: Freeze,

§

impl<Up, Down> !RefUnwindSafe for WorkerPool<Up, Down>

§

impl<Up, Down> Send for WorkerPool<Up, Down>

§

impl<Up, Down> !Sync for WorkerPool<Up, Down>

§

impl<Up, Down> Unpin for WorkerPool<Up, Down>
where Up: Unpin, Down: Unpin,

§

impl<Up, Down> !UnwindSafe for WorkerPool<Up, Down>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.