graphile_worker_admin_api 0.1.0

Shared Graphile Worker admin API contracts and queries
Documentation
use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct MaintenanceRequest {
    pub action: MaintenanceAction,
    #[serde(default)]
    pub cleanup_tasks: Vec<CleanupTaskName>,
    #[serde(default)]
    pub worker_ids: Vec<String>,
    #[serde(default)]
    pub dry_run: bool,
    pub sweep_threshold_secs: Option<u64>,
    pub recovery_delay_secs: Option<u64>,
}

#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub enum MaintenanceAction {
    Migrate,
    Cleanup,
    ForceUnlock,
    SweepStaleWorkers,
}

#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
pub enum CleanupTaskName {
    DeletePermanentlyFailedJobs,
    GcTaskIdentifiers,
    GcJobQueues,
}

impl CleanupTaskName {
    pub fn all() -> Vec<Self> {
        vec![
            Self::DeletePermanentlyFailedJobs,
            Self::GcTaskIdentifiers,
            Self::GcJobQueues,
        ]
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn cleanup_task_name_all_lists_every_cleanup_task() {
        let tasks = CleanupTaskName::all();

        assert_eq!(tasks.len(), 3);
        assert!(matches!(
            tasks.as_slice(),
            [
                CleanupTaskName::DeletePermanentlyFailedJobs,
                CleanupTaskName::GcTaskIdentifiers,
                CleanupTaskName::GcJobQueues
            ]
        ));
    }

    #[test]
    fn maintenance_request_deserializes_defaults() {
        let request: MaintenanceRequest =
            serde_json::from_value(serde_json::json!({ "action": "cleanup" })).unwrap();

        assert!(matches!(request.action, MaintenanceAction::Cleanup));
        assert!(request.cleanup_tasks.is_empty());
        assert!(request.worker_ids.is_empty());
        assert!(!request.dry_run);
        assert!(request.sweep_threshold_secs.is_none());
        assert!(request.recovery_delay_secs.is_none());
    }
}