runnerd_core/api/
events.rs1use serde::{Deserialize, Serialize};
6
7use super::jobs::{HostSample, JobSummary, Sample, Step};
8use super::{Budget, RepositoryStatus, SlotStatus};
9
10#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
13pub struct EventEnvelope {
14 pub id: Option<u64>,
16 pub at: u64,
18 #[serde(flatten)]
20 pub event: Event,
21}
22
23#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
25#[serde(tag = "type")]
26pub enum Event {
27 #[serde(rename = "job.queued")]
29 JobQueued {
30 job: JobSummary,
32 },
33 #[serde(rename = "job.started")]
35 JobStarted {
36 job: JobSummary,
38 },
39 #[serde(rename = "job.step")]
41 JobStep {
42 job: u64,
44 step: Step,
46 },
47 #[serde(rename = "job.finished")]
49 JobFinished {
50 job: JobSummary,
52 },
53 #[serde(rename = "slot.changed")]
55 SlotChanged {
56 profile: String,
58 slot: SlotStatus,
60 },
61 #[serde(rename = "budget.changed")]
63 BudgetChanged {
64 budget: Budget,
66 },
67 #[serde(rename = "repository.changed")]
70 RepositoryChanged {
71 repository: RepositoryStatus,
73 },
74 #[serde(rename = "repository.removed")]
76 RepositoryRemoved {
77 repository: String,
79 },
80 #[serde(rename = "cache.reseeded")]
82 CacheReseeded {
83 profile: String,
85 output: String,
87 error: Option<String>,
89 },
90 #[serde(rename = "job.sample")]
92 JobSample {
93 job: u64,
95 sample: Sample,
97 },
98 #[serde(rename = "host.sample")]
100 HostSample {
101 sample: HostSample,
103 },
104 #[serde(rename = "log.line")]
106 LogLine {
107 job: u64,
109 line: u64,
111 text: String,
113 },
114}
115
116impl Event {
117 pub fn kind(&self) -> &'static str {
119 match self {
120 Event::JobQueued { .. } => "job.queued",
121 Event::JobStarted { .. } => "job.started",
122 Event::JobStep { .. } => "job.step",
123 Event::JobFinished { .. } => "job.finished",
124 Event::SlotChanged { .. } => "slot.changed",
125 Event::BudgetChanged { .. } => "budget.changed",
126 Event::RepositoryChanged { .. } => "repository.changed",
127 Event::RepositoryRemoved { .. } => "repository.removed",
128 Event::CacheReseeded { .. } => "cache.reseeded",
129 Event::JobSample { .. } => "job.sample",
130 Event::HostSample { .. } => "host.sample",
131 Event::LogLine { .. } => "log.line",
132 }
133 }
134
135 pub fn is_durable(&self) -> bool {
137 !matches!(
138 self,
139 Event::JobSample { .. } | Event::HostSample { .. } | Event::LogLine { .. }
140 )
141 }
142
143 pub fn job(&self) -> Option<u64> {
145 match self {
146 Event::JobQueued { job } | Event::JobStarted { job } | Event::JobFinished { job } => {
147 Some(job.id)
148 }
149 Event::JobStep { job, .. }
150 | Event::JobSample { job, .. }
151 | Event::LogLine { job, .. } => Some(*job),
152 Event::SlotChanged { .. }
153 | Event::BudgetChanged { .. }
154 | Event::RepositoryChanged { .. }
155 | Event::RepositoryRemoved { .. }
156 | Event::CacheReseeded { .. }
157 | Event::HostSample { .. } => None,
158 }
159 }
160}
161
162#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
164pub struct EventQuery {
165 pub job: Option<u64>,
167 #[serde(default)]
169 pub logs: bool,
170}
171
172impl EventQuery {
173 pub fn matches(&self, event: &Event) -> bool {
175 (self.logs || !matches!(event, Event::LogLine { .. }))
176 && self.job.is_none_or(|job| event.job() == Some(job))
177 }
178}