use chrono::{DateTime, Utc};
use forge_jobs::{ProcessRecord, QueueConfigRow, QueueCounts};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[non_exhaustive]
pub struct QueueOverviewDto {
pub name: String,
pub paused: bool,
pub max_workers: i32,
pub counts: StatusCountsDto,
pub processes: Vec<QueueProcessDto>,
pub retain_done_days: u32,
pub retain_dead_days: u32,
pub backoff_enabled: bool,
pub backoff_base_seconds: u32,
pub backoff_max_seconds: u32,
pub throttled_until: Option<DateTime<Utc>>,
pub oldest_pending_age_seconds: u64,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[non_exhaustive]
pub struct StatusCountsDto {
pub pending: u64,
pub scheduled: u64,
pub in_progress: u64,
pub done: u64,
pub failed: u64,
pub dead: u64,
}
impl From<QueueCounts> for StatusCountsDto {
fn from(c: QueueCounts) -> Self {
Self {
pending: c.pending,
scheduled: c.scheduled,
in_progress: c.in_progress,
done: c.done,
failed: c.failed,
dead: c.dead,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[non_exhaustive]
pub struct QueueProcessDto {
pub process_id: String,
pub queue_name: String,
pub host_id: String,
pub started_at: DateTime<Utc>,
pub heartbeat_at: DateTime<Utc>,
pub current_job_id: Option<String>,
}
impl From<ProcessRecord> for QueueProcessDto {
fn from(p: ProcessRecord) -> Self {
Self {
process_id: p.process_id,
queue_name: p.queue_name,
host_id: p.host_id,
started_at: p.started_at,
heartbeat_at: p.heartbeat_at,
current_job_id: p.current_job.map(|id| id.as_str().to_owned()),
}
}
}
#[must_use]
pub fn overview_dto(
cfg: QueueConfigRow,
counts: QueueCounts,
processes: Vec<ProcessRecord>,
oldest_pending_age_seconds: u64,
) -> QueueOverviewDto {
QueueOverviewDto {
name: cfg.name,
paused: cfg.paused,
max_workers: cfg.max_workers,
counts: counts.into(),
processes: processes.into_iter().map(Into::into).collect(),
retain_done_days: u32::try_from(cfg.retain_done_for_days).unwrap_or(7),
retain_dead_days: u32::try_from(cfg.retain_dead_for_days).unwrap_or(30),
backoff_enabled: cfg.backoff_enabled,
backoff_base_seconds: u32::try_from(cfg.backoff_base_seconds).unwrap_or(60),
backoff_max_seconds: u32::try_from(cfg.backoff_max_seconds).unwrap_or(1800),
throttled_until: cfg.throttled_until,
oldest_pending_age_seconds,
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SetBackoffRequest {
pub enabled: bool,
pub base_seconds: i32,
pub max_seconds: i32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[non_exhaustive]
pub struct StorageInfoDto {
pub backend: String,
pub fields: Vec<(String, String)>,
}
impl From<forge_jobs::StorageInfo> for StorageInfoDto {
fn from(info: forge_jobs::StorageInfo) -> Self {
Self {
backend: info.backend,
fields: info.fields,
}
}
}