use crate::shutdown::report::ShutdownPipelineReport;
use crate::shutdown::stage::{ShutdownCause, ShutdownPhase, ShutdownPolicy};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ShutdownResult {
pub phase: ShutdownPhase,
pub cause: ShutdownCause,
pub idempotent: bool,
pub report: Option<ShutdownPipelineReport>,
}
#[derive(Debug, Clone)]
pub struct ShutdownCoordinator {
pub policy: ShutdownPolicy,
phase: ShutdownPhase,
cause: Option<ShutdownCause>,
}
impl ShutdownCoordinator {
pub fn new(policy: ShutdownPolicy) -> Self {
Self {
policy,
phase: ShutdownPhase::Idle,
cause: None,
}
}
pub fn request_stop(&mut self, cause: ShutdownCause) -> ShutdownResult {
if let Some(existing) = self.cause.clone() {
return self.result(existing, true);
}
self.phase = ShutdownPhase::RequestStop;
self.cause = Some(cause.clone());
self.result(cause, false)
}
pub fn advance(&mut self) -> ShutdownPhase {
if let Some(next) = self.phase.next() {
self.phase = next;
}
self.phase
}
pub fn complete(&mut self) -> ShutdownPhase {
self.phase = ShutdownPhase::Completed;
self.phase
}
pub fn phase(&self) -> ShutdownPhase {
self.phase
}
pub fn cause(&self) -> Option<&ShutdownCause> {
self.cause.as_ref()
}
pub fn result_with_report(
&self,
report: ShutdownPipelineReport,
idempotent: bool,
) -> ShutdownResult {
ShutdownResult {
phase: self.phase,
cause: report.cause.clone(),
idempotent,
report: Some(report),
}
}
fn result(&self, cause: ShutdownCause, idempotent: bool) -> ShutdownResult {
ShutdownResult {
phase: self.phase,
cause,
idempotent,
report: None,
}
}
}