carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package moves
2
3import "time"
4
5// The steps of a StoppedReport, in §5.3's order. StepTree to StepLease
6// are what stopevidence.Reconstruct observes from the box's durable state;
7// StepReplica is the caller's (the cut's step 5: the final checkpoint and
8// the digests), set after the checkpoint.
9const (
10 // StepTree: the host's cgroup was killed and drained (or never existed).
11 StepTree = "tree"
12 // StepStray: the agent's own cgroup leaf holds only the agent.
13 StepStray = "stray"
14 // StepFDs: no visible process holds the database, its WAL or its SHM.
15 StepFDs = "fds"
16 // StepLease: the host's lock.json is absent, released, or expired by
17 // more than the lease's renewal margin.
18 StepLease = "lease"
19 // StepReplica: the final checkpoint reached the replica.
20 StepReplica = "replica"
21)
22
23// treeSteps are §5.3 steps 1 to 4, what `stopping` needs before the final
24// checkpoint. allSteps adds the replica.
25var (
26 treeSteps = [...]string{StepTree, StepStray, StepFDs, StepLease}
27 allSteps = [...]string{StepTree, StepStray, StepFDs, StepLease, StepReplica}
28)
29
30// StoppedReport is a role's stop evidence for one move operation (§5.3),
31// written to moves/<acct>/<app>/<host>/<op id>/stopped-<role>.json. Every
32// observation is from durable, observable state, so a restarted agent
33// writes the same report. Steps holds one Check per step id; a step that
34// never ran is absent, and an absent step is not OK. Stray lists the pids
35// StepStray found in the agent's leaf besides the agent, for the alert. A 0
36// in it marks members the box could not identify (not visible in its pid
37// namespace).
38type StoppedReport struct {
39 V int `json:"v"`
40 Role string `json:"role"`
41 Box string `json:"box"`
42 Incarnation string `json:"incarnation"`
43 ClaimGen uint64 `json:"claim_gen"`
44 Host string `json:"host"`
45 OpID string `json:"op_id"`
46 Steps map[string]Check `json:"steps"`
47 Stray []int `json:"stray,omitempty"`
48 FinalTXID uint64 `json:"final_txid"`
49 DBSHA256 string `json:"db_sha256"`
50 FilesPlain string `json:"files_plain"`
51 TimersSHA256 string `json:"timers_sha256"`
52 CheckedAt time.Time `json:"checked_at"`
53}
54
55// TreeStopped reports §5.3 steps 1 to 4 all present and OK: the writer has
56// fully stopped, so the final checkpoint may run.
57func (r StoppedReport) TreeStopped() bool {
58 return r.stepsOK(treeSteps[:])
59}
60
61// Complete reports every step OK, StepReplica included. It fails closed on
62// any other step recorded in the report and not OK, so a step a later
63// version adds cannot be ignored by an older reader.
64func (r StoppedReport) Complete() bool {
65 if !r.stepsOK(allSteps[:]) {
66 return false
67 }
68 for _, c := range r.Steps {
69 if !c.OK {
70 return false
71 }
72 }
73 return true
74}
75
76func (r StoppedReport) stepsOK(ids []string) bool {
77 for _, id := range ids {
78 if c, ok := r.Steps[id]; !ok || !c.OK {
79 return false
80 }
81 }
82 return true
83}
84