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
//! Reading the volatile worker progress note of one attempt — honestly.
//!
//! A worker heartbeat may carry an opaque progress payload ("what I am doing
//! right now"). The server holds the most recent one per in-flight attempt in
//! [`HeartbeatTracker`], in memory, and writes it nowhere. That makes the read
//! path a measurement problem rather than a lookup: the absence of a note has
//! two completely different causes, and collapsing them would tell an operator
//! that a busy worker has gone silent every time the server was restarted.
//!
//! So the read returns [`AttemptProgress`], which never says "no note" without
//! saying which kind of no:
//!
//! - [`AttemptProgress::Reported`] — the tracker holds a note for this attempt.
//! - [`AttemptProgress::NoneSent`] — the tracker holds the ATTEMPT and no note
//! on it. This is a measurement: the worker really has reported nothing.
//! - [`AttemptProgress::Untracked`] — the tracker does not hold the attempt, so
//! there is nothing to measure. A restart is the usual cause (the notes were
//! in a process that no longer exists), and the other causes — the owner was
//! swept off the tracker, or nothing has leased the dispatch — are equally
//! unmeasurable from here. Every one of them is this variant; none of them is
//! ever reported as silence.
use ;
use ;
use ;
use crateServerError;
/// What this server process can say about one attempt's progress note.
/// The progress note this process holds for `(workflow, activity, attempt)`.
///
/// When a within-attempt failover has both a dying owner and its adopter
/// tracked, the entry with the most recent heartbeat wins: it is the one still
/// being fed, and taking the other would report a note the live worker has
/// already superseded. `last_heartbeat_at` is a monotonic [`std::time::Instant`]
/// minted by this process, so comparing entries is meaningful even though the
/// value itself would be meaningless to report.
///
/// # Errors
///
/// Returns [`ServerError::LockPoisoned`] when the tracker state cannot be read.
/// An unreadable tracker is reported, never rendered as "no note" — that would
/// be the exact confusion this module exists to prevent.
/// The tracked entry with the most recent heartbeat.