Crate poolio

source ·
Expand description

poolio is a thread-pool implementation using only channels for concurrency.

Design

A poolio thread-pool is essentially made up of a ‘supervisor’-thread and a specified number of ‘worker’-threads. A worker’s only purpose is executing jobs (in the guise of closures) while the supervisor is responsible for anything else, like - most importantly - assigning jobs to workers it gets from outside the pool via the public API. To this end, the thread-pool is set up in such a way that the supervisor can communicate with each worker seperately but concurrently. This, in particular, ensures that each worker is equally busy. A single supervisor-worker-communication is roughly as follows:

  1. worker tells the supervisor its current status
  2. supervisor decides what to tell the worker to do on the basis of the current order-message from outside the pool and the worker-status
  3. supervisor tells the work what to do
  4. worker tries to do what it was told by the supervisor
  5. worker tells the supervisor its current status

The following graphic illustrates the aformentioned communication-model of a supervisor-thread S and a worker-thread W:

   W
   _
   .
   .
   send-status
   .   O
   .     O
   .       O                 send-message
   .         O                   O
   .           O               O
   recv         recv         O
  * .  O       O  . .      O
 .   .   O   O   .   .   O
.     e    O    m     recv . . | S
 .   .   O   O   .   *
  . .  O       O  . .
   send-status  send-message

X | . . * : arrow starting at | and ending at * representing the control-flow of thread X
O O O O O : channel
e : execute job
m : manage workers

Usage

To use a poolio-ThreadPool you simply have to set one up using the ThreadPool::new-method and task the pool to run jobs using the ThreadPool::execute-method.

Examples

Setting up a pool to make some server multi-threaded:

fn handle(req: usize) {
    println!("Handled!")
}

let server_requests = [1, 2, 3, 4, 5, 6, 7, 8, 9];

let pool = poolio::ThreadPool::new(3, poolio::PanicSwitch::Kill).unwrap();

for req in server_requests {
    pool.execute(move || {
        handle(req);
    });
}

Structs

Enums

  • Configures what the ThreadPool is supposed to do in case of a ‘panicking job’, that is, a job which panics while running in a thread.