extern crate env_logger;
#[macro_use]
extern crate log;
extern crate closer;
extern crate wild_thread_pool;
use std::thread;
use std::time::Duration;
use std::borrow::Cow;
use std::error::Error;
use std::fmt::{self, Display};
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use wild_thread_pool::{ThreadPool, NewWorker, Worker, DefaultShutdown, ErrorExt};
fn main() {
env_logger::init().unwrap();
let closer = closer::Closer::init();
let thread_pool = ThreadPool::new(
2,
Duration::from_secs(2),
Duration::from_secs(2),
closer.closed(),
);
let new_hello_worker = NewHelloWorker::new();
let workes = thread_pool.run(new_hello_worker);
workes.wait().unwrap();
}
struct NewHelloWorker {
global_counter: Arc<AtomicUsize>,
}
impl NewHelloWorker {
fn new() -> NewHelloWorker {
NewHelloWorker { global_counter: Arc::new(AtomicUsize::new(0)) }
}
}
impl NewWorker for NewHelloWorker {
type Worker = HelloWorker;
fn new_worker(&self, worker_id: u64) -> Self::Worker {
HelloWorker::new(worker_id, self.global_counter.clone())
}
}
#[derive(Debug)]
struct Err(Cow<'static, str>);
impl Error for Err {
fn description(&self) -> &str {
self.0.as_ref()
}
}
impl Display for Err {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl ErrorExt for Err {
fn new_err(s: Cow<'static, str>) -> Self {
Err(s)
}
}
#[derive(Clone)]
struct HelloWorker {
worker_id: u64,
global_counter: Arc<AtomicUsize>,
worker_counter: Arc<AtomicUsize>,
}
impl HelloWorker {
fn new(worker_id: u64, global_counter: Arc<AtomicUsize>) -> HelloWorker {
let worker_counter = Arc::new(AtomicUsize::new(0));
HelloWorker {
worker_id,
global_counter,
worker_counter,
}
}
}
impl Worker for HelloWorker {
type Shutdown = DefaultShutdown;
type Err = Err;
fn worker_id(&self) -> u64 {
self.worker_id
}
fn on_tick(&self) -> Result<(), Err> {
self.global_counter.fetch_add(1, Ordering::Relaxed);
self.worker_counter.fetch_add(1, Ordering::Relaxed);
let global_counter = self.global_counter.load(Ordering::Relaxed);
let worker_counter = self.worker_counter.load(Ordering::Relaxed);
info!(
"worker-{}, tick, global_counter = {}, worker_counter = {}",
self.worker_id,
global_counter,
worker_counter
);
thread::sleep(Duration::from_secs(2));
Ok(())
}
fn new_shutdown(&self) -> Self::Shutdown {
DefaultShutdown::new(self.worker_id)
}
}