1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
//! What a run tells the outside world: the [`RunEvent`] stream a run emits
//! while it happens, and the [`RunSummary`] it ends with.
//!
//! This is the only contract between execution and display: the headless
//! CLI renderer today, and a TUI later, are two consumers of the same
//! stream. Nothing here knows how a
//! beam runs — [`crate::scheduler`] produces these values, and the channel
//! they travel on is unbounded, so a slow consumer never stalls the run.
use Duration;
use BeamId;
use OutputLine;
/// One thing that happened during a run.
///
/// Per beam, the order is `BeamStarted`, then every `BeamOutput`, then
/// `BeamFinished` — a beam that runs several commands still emits exactly
/// one started/finished pair, since the individual commands are an
/// implementation detail of the beam. A cache hit follows the same shape
/// with `BeamCached` in place of `BeamStarted`: the same replayed
/// `BeamOutput` lines, then `BeamFinished` with [`BeamStatus::Cached`]. A
/// beam that never ran (cancelled before it acquired a slot, or skipped
/// because a dependency failed) emits only `BeamFinished` with
/// [`BeamStatus::Cancelled`]. Events from different beams interleave
/// freely; `RunStarted` is first *per run*, before any
/// `BeamStarted`/`BeamCached`; `RunFinished` is last *per run* — in a watch
/// session, it is followed by `WatchWaiting` and, once a change is seen,
/// `WatchTriggered` before the next run's events begin.
/// How a beam ended.
///
/// `Failed` and `FailedAllowed` are the same event seen through the beam's
/// `allow_failure` flag: a `FailedAllowed` beam counts as satisfied for its
/// dependents, never triggers fail-fast, and does not affect the run's exit
/// code. `Cancelled` covers both reasons a beam can be skipped: a
/// dependency that failed or was itself cancelled, and a run-wide stop
/// (fail-fast, or the caller's cancellation token).
/// What a whole run amounts to: every beam of the target's subgraph sorted
/// into the bucket it ended in, plus how long the run took.
///
/// The five vectors are in the project's declaration order, never in
/// completion order — a run is a concurrent thing, and ordering the summary
/// by whichever task happened to finish first would make it differ from run
/// to run for the same project.