systemprompt-scheduler 0.2.2

Background jobs, cron tasks, and job-extension dispatch for systemprompt.io AI governance infrastructure. Tokio-backed scheduling for the MCP governance pipeline.
Documentation
use super::state_types::{DesiredStatus, RuntimeStatus, ServiceAction, ServiceType};
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VerifiedServiceState {
    pub name: String,
    pub service_type: ServiceType,
    pub desired_status: DesiredStatus,
    pub runtime_status: RuntimeStatus,
    pub pid: Option<u32>,
    pub port: u16,
    pub needs_action: ServiceAction,
    pub error: Option<String>,
}

#[derive(Debug)]
pub struct VerifiedServiceStateBuilder {
    name: String,
    service_type: ServiceType,
    desired: DesiredStatus,
    runtime: RuntimeStatus,
    port: u16,
    pid: Option<u32>,
    error: Option<String>,
}

impl VerifiedServiceStateBuilder {
    pub const fn new(
        name: String,
        service_type: ServiceType,
        desired: DesiredStatus,
        runtime: RuntimeStatus,
        port: u16,
    ) -> Self {
        Self {
            name,
            service_type,
            desired,
            runtime,
            port,
            pid: None,
            error: None,
        }
    }

    pub const fn with_pid(mut self, pid: u32) -> Self {
        self.pid = Some(pid);
        self
    }

    pub fn with_error(mut self, error: String) -> Self {
        self.error = Some(error);
        self
    }

    pub fn build(self) -> VerifiedServiceState {
        let action = VerifiedServiceState::determine_action(&self.desired, &self.runtime);
        VerifiedServiceState {
            name: self.name,
            service_type: self.service_type,
            desired_status: self.desired,
            runtime_status: self.runtime,
            pid: self.pid,
            port: self.port,
            needs_action: action,
            error: self.error,
        }
    }
}

impl VerifiedServiceState {
    pub const fn builder(
        name: String,
        service_type: ServiceType,
        desired: DesiredStatus,
        runtime: RuntimeStatus,
        port: u16,
    ) -> VerifiedServiceStateBuilder {
        VerifiedServiceStateBuilder::new(name, service_type, desired, runtime, port)
    }

    const fn determine_action(desired: &DesiredStatus, runtime: &RuntimeStatus) -> ServiceAction {
        match (desired, runtime) {
            (DesiredStatus::Enabled, RuntimeStatus::Running | RuntimeStatus::Starting) => {
                ServiceAction::None
            },
            (DesiredStatus::Enabled, RuntimeStatus::Stopped) => ServiceAction::Start,
            (DesiredStatus::Enabled, RuntimeStatus::Crashed | RuntimeStatus::Orphaned) => {
                ServiceAction::Restart
            },
            (DesiredStatus::Disabled, RuntimeStatus::Running | RuntimeStatus::Starting) => {
                ServiceAction::Stop
            },
            (DesiredStatus::Disabled, RuntimeStatus::Stopped | RuntimeStatus::Crashed) => {
                ServiceAction::CleanupDb
            },
            (DesiredStatus::Disabled, RuntimeStatus::Orphaned) => ServiceAction::CleanupProcess,
        }
    }

    pub const fn is_healthy(&self) -> bool {
        matches!(
            (&self.desired_status, &self.runtime_status),
            (
                DesiredStatus::Enabled,
                RuntimeStatus::Running | RuntimeStatus::Starting
            )
        )
    }

    pub const fn needs_attention(&self) -> bool {
        !matches!(self.needs_action, ServiceAction::None)
    }

    pub const fn status_display(&self) -> &'static str {
        match self.runtime_status {
            RuntimeStatus::Running => "running",
            RuntimeStatus::Starting => "starting",
            RuntimeStatus::Stopped => "stopped",
            RuntimeStatus::Crashed => "crashed",
            RuntimeStatus::Orphaned => "orphaned",
        }
    }

    pub const fn action_display(&self) -> &'static str {
        match self.needs_action {
            ServiceAction::None => "-",
            ServiceAction::Start => "start",
            ServiceAction::Stop => "stop",
            ServiceAction::Restart => "restart",
            ServiceAction::CleanupDb => "cleanup-db",
            ServiceAction::CleanupProcess => "cleanup-process",
        }
    }
}