1use serde::{Deserialize, Serialize};
6
7use super::jobs::{HostSample, JobSummary, Sample, Step};
8use super::{
9 Budget, ProfileStatus, Record, RecordRemoval, RepositoryStatus, SizingChange, SlotStatus,
10};
11
12#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
15pub struct EventEnvelope {
16 pub id: Option<u64>,
18 pub at: u64,
20 #[serde(flatten)]
22 pub event: Event,
23}
24
25#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
27#[serde(tag = "type")]
28pub enum Event {
29 #[serde(rename = "job.queued")]
31 JobQueued {
32 job: JobSummary,
34 },
35 #[serde(rename = "job.started")]
37 JobStarted {
38 job: JobSummary,
40 },
41 #[serde(rename = "job.step")]
43 JobStep {
44 job: u64,
46 step: Step,
48 },
49 #[serde(rename = "job.finished")]
51 JobFinished {
52 job: JobSummary,
54 },
55 #[serde(rename = "slot.changed")]
57 SlotChanged {
58 profile: String,
60 slot: SlotStatus,
62 },
63 #[serde(rename = "profile.changed")]
67 ProfileChanged {
68 profile: ProfileStatus,
70 },
71 #[serde(rename = "profile.removed")]
73 ProfileRemoved {
74 profile: String,
76 },
77 #[serde(rename = "budget.changed")]
79 BudgetChanged {
80 budget: Budget,
82 },
83 #[serde(rename = "repository.changed")]
86 RepositoryChanged {
87 repository: RepositoryStatus,
89 },
90 #[serde(rename = "repository.removed")]
92 RepositoryRemoved {
93 repository: String,
95 },
96 #[serde(rename = "cache.reseeded")]
98 CacheReseeded {
99 profile: String,
101 output: String,
103 error: Option<String>,
105 },
106 #[serde(rename = "record.created")]
108 RecordCreated {
109 record: Record,
111 },
112 #[serde(rename = "record.deleted")]
114 RecordDeleted {
115 job: u64,
117 removed_by: RecordRemoval,
119 },
120 #[serde(rename = "sizing.changed")]
122 SizingChanged {
123 change: SizingChange,
125 },
126 #[serde(rename = "job.sample")]
128 JobSample {
129 job: u64,
131 sample: Sample,
133 },
134 #[serde(rename = "host.sample")]
136 HostSample {
137 sample: HostSample,
139 },
140 #[serde(rename = "log.line")]
142 LogLine {
143 job: u64,
145 line: u64,
147 text: String,
149 },
150}
151
152impl Event {
153 pub fn kind(&self) -> &'static str {
155 match self {
156 Event::JobQueued { .. } => "job.queued",
157 Event::JobStarted { .. } => "job.started",
158 Event::JobStep { .. } => "job.step",
159 Event::JobFinished { .. } => "job.finished",
160 Event::SlotChanged { .. } => "slot.changed",
161 Event::ProfileChanged { .. } => "profile.changed",
162 Event::ProfileRemoved { .. } => "profile.removed",
163 Event::BudgetChanged { .. } => "budget.changed",
164 Event::RepositoryChanged { .. } => "repository.changed",
165 Event::RepositoryRemoved { .. } => "repository.removed",
166 Event::CacheReseeded { .. } => "cache.reseeded",
167 Event::RecordCreated { .. } => "record.created",
168 Event::RecordDeleted { .. } => "record.deleted",
169 Event::SizingChanged { .. } => "sizing.changed",
170 Event::JobSample { .. } => "job.sample",
171 Event::HostSample { .. } => "host.sample",
172 Event::LogLine { .. } => "log.line",
173 }
174 }
175
176 pub fn is_durable(&self) -> bool {
178 !matches!(
179 self,
180 Event::JobSample { .. } | Event::HostSample { .. } | Event::LogLine { .. }
181 )
182 }
183
184 pub fn job(&self) -> Option<u64> {
186 match self {
187 Event::JobQueued { job } | Event::JobStarted { job } | Event::JobFinished { job } => {
188 Some(job.id)
189 }
190 Event::JobStep { job, .. }
191 | Event::JobSample { job, .. }
192 | Event::LogLine { job, .. }
193 | Event::RecordDeleted { job, .. } => Some(*job),
194 Event::RecordCreated { record } => Some(record.job),
195 Event::SlotChanged { .. }
196 | Event::ProfileChanged { .. }
197 | Event::ProfileRemoved { .. }
198 | Event::BudgetChanged { .. }
199 | Event::RepositoryChanged { .. }
200 | Event::RepositoryRemoved { .. }
201 | Event::CacheReseeded { .. }
202 | Event::SizingChanged { .. }
203 | Event::HostSample { .. } => None,
204 }
205 }
206}
207
208#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
210pub struct EventQuery {
211 pub job: Option<u64>,
213 #[serde(default)]
215 pub logs: bool,
216}
217
218impl EventQuery {
219 pub fn matches(&self, event: &Event) -> bool {
221 (self.logs || !matches!(event, Event::LogLine { .. }))
222 && self.job.is_none_or(|job| event.job() == Some(job))
223 }
224}