use std::sync::Arc;
use crate::core::{
AddOperation, CancelOperation, OwnershipSnapshot, RemoveOperation, RuntimeOwner,
SupervisorCore, TaskTarget, TerminationUnbounded, Unwatched, Waiting,
};
use crate::error::RuntimeError;
use crate::identity::TaskId;
use crate::tasks::TaskSpec;
#[derive(Clone)]
pub struct SupervisorHandle {
owner: Arc<RuntimeOwner>,
#[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.owner.core())
.finish_non_exhaustive()
}
}
impl SupervisorHandle {
pub(crate) fn new(owner: Arc<RuntimeOwner>) -> Self {
Self {
owner,
#[cfg(feature = "controller")]
controller: None,
}
}
pub(super) fn core(&self) -> &Arc<SupervisorCore> {
self.owner.core()
}
#[cfg(feature = "controller")]
pub(super) fn controller(&self) -> Option<&crate::controller::Controller> {
self.controller.as_deref()
}
#[cfg(feature = "controller")]
pub(crate) fn with_controller(
mut self,
controller: Option<Arc<crate::controller::Controller>>,
) -> Self {
self.controller = controller;
self
}
#[must_use = "await the default add or configure and execute the operation"]
#[inline]
pub fn add(&self, spec: TaskSpec) -> AddOperation<'_, Unwatched, Waiting> {
AddOperation::new(self.core(), spec)
}
#[must_use = "configure and execute the remove operation"]
#[inline]
pub fn remove<Target>(&self, target: Target) -> RemoveOperation<'_, Waiting, Target>
where
Target: Into<TaskTarget>,
{
RemoveOperation::new(self, target)
}
#[must_use = "configure and execute the cancel operation"]
#[inline]
pub fn cancel<Target>(
&self,
target: Target,
) -> CancelOperation<'_, Waiting, TerminationUnbounded, Target>
where
Target: Into<TaskTarget>,
{
CancelOperation::new(self, target)
}
pub async fn list(&self) -> Vec<(TaskId, Arc<str>)> {
self.core().list_tasks().await
}
pub async fn alive_snapshot(&self) -> Vec<Arc<str>> {
self.core().snapshot().await
}
pub async fn is_alive(&self, name: &str) -> bool {
self.core().is_alive(name).await
}
#[must_use = "inspect the returned ownership state"]
pub fn ownership_snapshot(&self) -> OwnershipSnapshot {
self.core().ownership_snapshot()
}
#[must_use = "inspect the returned runtime configuration"]
pub fn runtime_config(&self) -> &crate::SupervisorConfig {
self.core().runtime_config()
}
#[must_use = "inspect the returned task defaults"]
pub fn task_defaults(&self) -> &crate::TaskDefaults {
self.core().task_defaults()
}
#[doc(alias = "graceful shutdown")]
#[doc(alias = "graceful stop")]
pub async fn shutdown(self) -> Result<(), RuntimeError> {
self.core().shutdown().await
}
#[cfg(feature = "controller")]
#[cfg_attr(docsrs, doc(cfg(feature = "controller")))]
pub fn prepare_submission(
&self,
spec: crate::controller::ControllerSpec,
) -> Result<crate::controller::PreparedSubmission, crate::controller::ControllerError> {
match &self.controller {
Some(controller) => Ok(crate::controller::PreparedSubmission::new(
controller.handle(),
spec,
)),
None => Err(crate::controller::ControllerError::NotConfigured),
}
}
#[cfg(feature = "controller")]
#[cfg_attr(docsrs, doc(cfg(feature = "controller")))]
#[must_use = "await the default submission or configure and execute the operation"]
#[inline]
pub fn submit(&self, spec: crate::controller::ControllerSpec) -> crate::controller::Submit<'_> {
crate::controller::Submit::direct(self.controller.as_deref(), spec)
}
#[cfg(feature = "controller")]
#[cfg_attr(docsrs, doc(cfg(feature = "controller")))]
pub async fn controller_snapshot(&self) -> Option<crate::controller::ControllerSnapshot> {
match &self.controller {
Some(controller) => Some(controller.snapshot().await),
None => None,
}
}
}