dynpool 0.0.2

A thread manager that is lightweight, flexible, and rescalable.
Documentation
[![Build Status](https://gitlab.com/samsartor/dynpool/badges/master/build.svg)](https://gitlab.com/samsartor/dynpool/commits/master)

# Dynpool

Dynpool is a thread manager that is lightweight, flexible, and rescalable.
The pool is designed for minimal overhead, without expensive locks or an
extra management thread. Add a job queue yourself, or don't!

To use dynpool, all you need is an implementation of `System`. The pool will
repeatedly call `System::work` from many threads, each with a per-thread
data object. Rather than requiring you to rescale the pool from the outside,
`dynpool` will constantly query the worker count from `System::scale`. This
is actually faster, since a simple `scale` implementation can be inlined
into the worker! Your system can be run in the background, and controlled
through the `Pool` object, or run in the foreground to make use of the
current thread.

```rust
struct Printer(Instant);

impl System for Printer {
    type Data = String;

    // How many threads? The pool will scale up over time!
    fn scale(&self) -> Scale {
        let time = self.0.elapsed();
        let ms = time.as_secs() * 1000 + time.subsec_millis() as u64;
        match ms {
            0..=200 => Scale::active(1),
            201..=400 => Scale::active(2),
            401..=600 => Scale::active(3),
            601..=800 => Scale::active(4),
            _ => Scale::shutdown(),
        }
    }

    // Pick a string for each thread.
    fn init(&self, index: usize) -> String {
        match index {
            0 => "Hello",
            1 => "Hola",
            2 => "Bonjour",
            3 => "Ciao",
            _ => unreachable!(),
        }.to_owned()
    }

    // Do work on several threads!
    fn work(&self, text: &mut String) -> Decision {
        println!("{}", text);
        *text += " Again";
        sleep(Duration::from_millis(100));
        Decision::Again
    }
}

fn main() {
    Pool::start_fg(Printer(Instant::now())).unwrap();
    println!("This is the end!");
}
```

There are also builtin functions for concisely altering and constructing systems.

```rust
let workers = func_worker(|index| {
    println!("New worker #{}", index);
    move || {
        println!("Hello from #{}", index);
        Decision::Again
    }
});
let sys = with_threads(workers, 10);
let end_time = Instant::now() + Duration::from_millis(500);
Pool::start_fg(shutdown_after(sys, end_time)).unwrap();
```