use std::{
thread::{self, JoinHandle},
time::Duration,
};
use crossbeam_channel::Receiver;
use crate::task::Task;
pub struct Worker {
pub(crate) is_core: bool,
receiver: Receiver<Task>,
keep_alive_time: Duration,
thread: JoinHandle<()>,
}
fn create_core_work_thread(receiver: Receiver<Task>, task: Task) -> JoinHandle<()> {
thread::spawn(move || {
task.run();
while let Ok(task) = receiver.recv() {
task.run();
}
})
}
fn create_work_thread(
receiver: Receiver<Task>,
task: Task,
keep_alive_time: Duration,
) -> JoinHandle<()> {
thread::spawn(move || {
task.run();
while let Ok(task) = receiver.recv_timeout(keep_alive_time) {
task.run();
}
})
}
impl Worker {
#[must_use]
pub fn new(
is_core: bool,
keep_alive_time: Duration,
receiver: Receiver<Task>,
task: Task,
) -> Self {
Worker {
is_core,
keep_alive_time,
receiver: receiver.clone(),
thread: if is_core {
create_core_work_thread(receiver, task)
} else {
create_work_thread(receiver, task, keep_alive_time)
},
}
}
pub(crate) fn restart(&mut self, task: Task) {
debug_assert!(self.is_finished() && !self.is_core);
self.thread = create_work_thread(self.receiver.clone(), task, self.keep_alive_time);
}
#[inline]
pub fn is_finished(&self) -> bool {
self.thread.is_finished()
}
#[inline]
pub(crate) fn join(self) -> thread::Result<()> {
self.thread.join()
}
}