use crate::id::types::{Attempt, ChildId, Generation, SupervisorPath};
use crate::readiness::signal::ReadySignal;
use tokio::sync::watch;
use tokio::time::Instant;
use tokio_util::sync::CancellationToken;
#[derive(Debug, Clone)]
pub struct TaskContext {
pub child_id: ChildId,
pub path: SupervisorPath,
pub generation: Generation,
pub attempt: Attempt,
cancellation_token: CancellationToken,
ready_signal: ReadySignal,
heartbeat_sender: watch::Sender<Option<Instant>>,
}
impl TaskContext {
pub fn new(
child_id: ChildId,
path: SupervisorPath,
generation: Generation,
attempt: Attempt,
) -> (Self, watch::Receiver<Option<Instant>>) {
let (ready_signal, _ready_receiver) = ReadySignal::new();
let (heartbeat_sender, heartbeat_receiver) = watch::channel(None);
(
Self {
child_id,
path,
generation,
attempt,
cancellation_token: CancellationToken::new(),
ready_signal,
heartbeat_sender,
},
heartbeat_receiver,
)
}
pub fn with_ready_signal(
child_id: ChildId,
path: SupervisorPath,
generation: Generation,
attempt: Attempt,
ready_signal: ReadySignal,
) -> (Self, watch::Receiver<Option<Instant>>) {
let (heartbeat_sender, heartbeat_receiver) = watch::channel(None);
(
Self {
child_id,
path,
generation,
attempt,
cancellation_token: CancellationToken::new(),
ready_signal,
heartbeat_sender,
},
heartbeat_receiver,
)
}
pub fn mark_ready(&self) {
self.ready_signal.mark_ready();
}
pub fn heartbeat(&self) {
let _ignored = self.heartbeat_sender.send(Some(Instant::now()));
}
pub fn cancel(&self) {
self.cancellation_token.cancel();
}
pub fn is_cancelled(&self) -> bool {
self.cancellation_token.is_cancelled()
}
pub fn cancellation_token(&self) -> CancellationToken {
self.cancellation_token.clone()
}
pub fn readiness_receiver(&self) -> watch::Receiver<bool> {
self.ready_signal.subscribe()
}
}