crankshaft_events/lib.rs
1//! Definition of the events broadcast by Crankshaft.
2
3use std::process::ExitStatus;
4use std::sync::atomic::AtomicU64;
5use std::sync::atomic::Ordering;
6
7use bytes::Bytes;
8use nonempty::NonEmpty;
9use tokio_util::sync::CancellationToken;
10
11/// Represents a Crankshaft task identifier.
12pub type TaskId = u64;
13
14/// Gets the next task id.
15pub fn next_task_id() -> TaskId {
16 static NEXT_TASK_ID: AtomicU64 = AtomicU64::new(0);
17 NEXT_TASK_ID.fetch_add(1, Ordering::SeqCst)
18}
19
20/// An event sent by task execution backends.
21#[derive(Debug, Clone)]
22pub enum Event {
23 /// A task has been created.
24 ///
25 /// Note: a task is not "running" until the [`Event::TaskStarted`] event.
26 ///
27 /// This event is always paired with a `TaskCompleted`, `TaskFailed`,
28 /// `TaskCanceled`, or `TaskPreempted` event.
29 TaskCreated {
30 /// The id of the task.
31 id: TaskId,
32 /// The name of the task.
33 ///
34 /// This may be a display name provided by the user or a name provided
35 /// by the backend if the user did not provide a name for the task.
36 name: String,
37 /// The TES identifier of the task.
38 ///
39 /// This is `Some` only for the TES backend.
40 tes_id: Option<String>,
41
42 /// The cancellation token provided by the backend
43 token: CancellationToken,
44 },
45 /// A task has started execution.
46 ///
47 /// A task is considered "running" upon the receipt of this event.
48 TaskStarted {
49 /// The id of the task.
50 id: TaskId,
51 },
52 /// A container has been created for a task.
53 ///
54 /// This event is only sent by the Docker backend.
55 TaskContainerCreated {
56 /// The id of the task.
57 id: TaskId,
58 /// The name of the container that was created.
59 container: String,
60 },
61 /// A container has exited for a task.
62 ///
63 /// This event is only sent by the Docker backend.
64 TaskContainerExited {
65 /// The id of the task.
66 id: TaskId,
67 /// The name of the container that has exited.
68 container: String,
69 /// The exit status of the container.
70 exit_status: ExitStatus,
71 },
72 /// A task has completed.
73 ///
74 /// This event occurs after all task executions have completed successfully.
75 TaskCompleted {
76 /// The id of the task.
77 id: TaskId,
78 /// The exit statuses for the task's executions.
79 exit_statuses: NonEmpty<ExitStatus>,
80 },
81 /// A task has failed.
82 ///
83 /// This event occurs after any error encountered running a task.
84 TaskFailed {
85 /// The id of the task.
86 id: TaskId,
87 /// The error message.
88 message: String,
89 },
90 /// A task has been canceled.
91 TaskCanceled {
92 /// The id of the task.
93 id: TaskId,
94 },
95 /// The task was preempted.
96 TaskPreempted {
97 /// The id of the task.
98 id: TaskId,
99 },
100 /// A task has logged stdout.
101 ///
102 /// Note: only locally executing tasks will send this event.
103 TaskStdout {
104 /// The id of the task.
105 id: TaskId,
106 /// The bytes logged to stdout.
107 message: Bytes,
108 },
109 /// A task has logged stderr.
110 ///
111 /// Note: only locally executing tasks will send this event.
112 TaskStderr {
113 /// The id of the task.
114 id: TaskId,
115 /// The bytes logged to stdout.
116 message: Bytes,
117 },
118 /// A container image pull was started.
119 ///
120 /// ## Implementation Notes
121 ///
122 /// * This event indicates that an actual fetch process is initiated.
123 /// Backends **should not** emit this if the image is already present.
124 /// * Backends *may* emit this event multiple times for the same image if
125 /// multiple executions request it.
126 ///
127 /// This event is always paired with either an [`Event::ImagePullFinished`]
128 /// or [`Event::ImagePullFailed`] event.
129 ImagePullStarted {
130 /// The id of the task that triggered the pull.
131 id: TaskId,
132 /// The name of the image being pulled.
133 name: String,
134 },
135 /// Failed to pull a container image.
136 ///
137 /// Note: This indicates the termination of an image pull. It **will not**
138 /// be paired with an [`Event::ImagePullFinished`] event.
139 ImagePullFailed {
140 /// The id of the task that triggered the pull.
141 id: TaskId,
142 /// The name of the image that failed.
143 name: String,
144 /// The error message.
145 message: String,
146 },
147 /// A container image was successfully pulled.
148 ImagePullFinished {
149 /// The id of the task that triggered the pull.
150 id: TaskId,
151 /// The name of the image that was pulled.
152 name: String,
153 },
154}
155
156/// Sends an event through a broadcast channel.
157///
158/// If the sender is `None`, the event expression is not evaluated and no event
159/// is sent.
160#[macro_export]
161macro_rules! send_event {
162 ($sender:expr, $event:expr $(,)?) => {
163 if let Some(sender) = &$sender {
164 sender.send($event).ok();
165 }
166 };
167}