use crate::error::{BeaverError, BeaverResult};
use crate::listener::WorkListener;
use crate::task::{Task, TaskId};
use crate::work::Work;
use crate::work_fn::BoxWork;
use std::sync::atomic::AtomicBool;
use std::sync::Arc;
use std::time::Duration;
pub struct PeriodicTask {
pub(crate) id: TaskId,
pub(crate) work: BoxWork,
pub(crate) interval: Duration,
pub(crate) initial_delay: bool,
pub(crate) tag: Option<String>,
pub(crate) listener: Option<Arc<dyn WorkListener>>,
pub(crate) interrupted: AtomicBool,
}
pub struct PeriodicBuilder {
work: Option<BoxWork>,
interval: Duration,
initial_delay: bool,
tag: Option<String>,
listener: Option<Arc<dyn WorkListener>>,
}
impl PeriodicBuilder {
pub fn new<W>(work: W) -> Self
where
W: Work + Send + 'static,
{
PeriodicBuilder {
work: Some(Box::new(work)),
interval: Duration::ZERO, initial_delay: false,
tag: None,
listener: None,
}
}
pub fn interval(mut self, duration: Duration) -> Self {
self.interval = duration;
self
}
pub fn initial_delay(mut self, delay: bool) -> Self {
self.initial_delay = delay;
self
}
pub fn tag(mut self, tag: impl Into<String>) -> Self {
self.tag = Some(tag.into());
self
}
pub fn listener(mut self, listener: Arc<dyn WorkListener>) -> Self {
self.listener = Some(listener);
self
}
pub fn build(self) -> BeaverResult<Arc<Task>> {
let work = self.work.ok_or(BeaverError::BuilderMissingField("work"))?;
Ok(Arc::new(Task::Periodic(PeriodicTask {
id: TaskId::new(),
work,
interval: self.interval,
initial_delay: self.initial_delay,
tag: self.tag,
listener: self.listener,
interrupted: AtomicBool::new(false),
})))
}
}