use std::{sync::Arc, time::Duration};
use crate::core::SupervisorCore;
use crate::error::RuntimeError;
use crate::identity::TaskId;
use crate::tasks::TaskSpec;
use super::outcome::TaskWaiter;
#[derive(Clone)]
pub struct SupervisorHandle {
core: Arc<SupervisorCore>,
#[cfg(feature = "controller")]
controller: Option<Arc<crate::controller::Controller>>,
}
impl std::fmt::Debug for SupervisorHandle {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("SupervisorHandle")
.field("core", &self.core)
.finish_non_exhaustive()
}
}
impl SupervisorHandle {
pub(crate) fn new(core: Arc<SupervisorCore>) -> Self {
Self {
core,
#[cfg(feature = "controller")]
controller: None,
}
}
#[cfg(feature = "controller")]
pub(crate) fn with_controller(
mut self,
controller: Option<Arc<crate::controller::Controller>>,
) -> Self {
self.controller = controller;
self
}
pub async fn add(&self, spec: TaskSpec) -> Result<TaskId, RuntimeError> {
self.core.add_task(spec).await
}
pub async fn try_add(&self, spec: TaskSpec) -> Result<TaskId, RuntimeError> {
self.core.try_add_task(spec).await
}
pub async fn add_and_watch(
&self,
spec: TaskSpec,
) -> Result<(TaskId, TaskWaiter), RuntimeError> {
let (id, done_rx) = self.core.add_task_watched(spec).await?;
Ok((id, TaskWaiter::new(id, done_rx)))
}
pub async fn remove(&self, id: TaskId) -> Result<bool, RuntimeError> {
self.core.remove(id).await
}
pub async fn try_remove(&self, id: TaskId) -> Result<bool, RuntimeError> {
self.core.try_remove(id).await
}
pub async fn remove_by_label(&self, name: &str) -> Result<bool, RuntimeError> {
self.core.remove_by_label(Arc::from(name)).await
}
pub async fn list(&self) -> Vec<(TaskId, Arc<str>)> {
self.core.list_tasks().await
}
pub async fn snapshot(&self) -> Vec<Arc<str>> {
self.core.snapshot().await
}
pub async fn is_alive(&self, name: &str) -> bool {
self.core.is_alive(name).await
}
pub async fn cancel(&self, id: TaskId) -> Result<bool, RuntimeError> {
self.core.cancel(id).await
}
pub async fn cancel_by_label(&self, name: &str) -> Result<bool, RuntimeError> {
self.core.cancel_by_label(Arc::from(name)).await
}
pub async fn cancel_with_timeout(
&self,
id: TaskId,
wait_for: Duration,
) -> Result<bool, RuntimeError> {
self.core.cancel_with_timeout(id, wait_for).await
}
pub async fn shutdown(self) -> Result<(), RuntimeError> {
self.core.shutdown().await
}
#[cfg(feature = "controller")]
pub async fn submit(
&self,
spec: crate::controller::ControllerSpec,
) -> Result<TaskId, crate::controller::ControllerError> {
match &self.controller {
Some(ctrl) => ctrl.handle().submit(spec).await,
None => Err(crate::controller::ControllerError::NotConfigured),
}
}
#[cfg(feature = "controller")]
pub fn try_submit(
&self,
spec: crate::controller::ControllerSpec,
) -> Result<TaskId, crate::controller::ControllerError> {
match &self.controller {
Some(ctrl) => ctrl.handle().try_submit(spec),
None => Err(crate::controller::ControllerError::NotConfigured),
}
}
#[cfg(feature = "controller")]
pub async fn submit_and_watch(
&self,
spec: crate::controller::ControllerSpec,
) -> Result<(TaskId, TaskWaiter), crate::controller::ControllerError> {
match &self.controller {
Some(ctrl) => {
let (id, rx) = ctrl.handle().submit_and_watch(spec).await?;
Ok((id, TaskWaiter::new(id, rx)))
}
None => Err(crate::controller::ControllerError::NotConfigured),
}
}
#[cfg(feature = "controller")]
pub async fn controller_snapshot(&self) -> Option<crate::controller::ControllerSnapshot> {
match &self.controller {
Some(ctrl) => Some(ctrl.snapshot().await),
None => None,
}
}
}