Skip to main content

boson_core/models/
run.rs

1//! Run model — one execution attempt of a job.
2
3use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5
6/// Status of a run.
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
8#[serde(rename_all = "lowercase")]
9pub enum RunStatus {
10    /// Run is executing.
11    #[default]
12    Running,
13    /// Run completed successfully.
14    Success,
15    /// Run failed.
16    Failed,
17    /// Run was canceled.
18    Canceled,
19    /// Run timed out.
20    ///
21    /// Reserved for future worker timeout support; not set by the current runtime.
22    Timeout,
23}
24
25impl std::fmt::Display for RunStatus {
26    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27        match self {
28            Self::Running => write!(f, "running"),
29            Self::Success => write!(f, "success"),
30            Self::Failed => write!(f, "failed"),
31            Self::Canceled => write!(f, "canceled"),
32            Self::Timeout => write!(f, "timeout"),
33        }
34    }
35}
36
37/// One execution attempt of a job.
38#[derive(Debug, Clone, Serialize, Deserialize)]
39pub struct Run {
40    /// Unique identifier (UUID).
41    pub run_id: String,
42    /// Job this run belongs to.
43    pub job_id: String,
44    /// Task name (denormalized).
45    pub task_name: String,
46    /// Attempt number (1-based).
47    pub attempt: i32,
48    /// Status.
49    pub status: RunStatus,
50    /// When execution started.
51    pub started_at: DateTime<Utc>,
52    /// When execution finished (if terminal).
53    pub finished_at: Option<DateTime<Utc>>,
54    /// Duration in milliseconds (if finished).
55    pub duration_ms: Option<i64>,
56    /// Error message if failed.
57    pub error_message: Option<String>,
58}
59
60impl Run {
61    /// Create a new running run for a job.
62    #[must_use]
63    pub fn new(job_id: &str, task_name: &str, attempt: i32) -> Self {
64        Self {
65            run_id: uuid::Uuid::new_v4().to_string(),
66            job_id: job_id.to_string(),
67            task_name: task_name.to_string(),
68            attempt,
69            status: RunStatus::Running,
70            started_at: Utc::now(),
71            finished_at: None,
72            duration_ms: None,
73            error_message: None,
74        }
75    }
76}