The first pass after a start clears failed-alone for every module and known node (ADR 0557, issue 1496)
Review round 2 of 16e4e61: gating the first-pass clear on a failed have left a
condition an earlier process raised standing for good once its node recovered
while no assigner watched. The first pass now clears it for every module and
every node the presence bucket knows, a quiet clear at the router for one that
is not open.
This commit is contained in:
@@ -238,9 +238,9 @@ func (p *passer) sayNoWant(module string, nodes []string, before map[string]deli
|
||||
// sayNodeFailed raises, once per node and words, the condition of a failed health check of a module's newest fingerprint fp
|
||||
// that is the node's own, since fp runs healthy elsewhere and is not held (ADR 0557 §1, issue 1496), and says it in the journal;
|
||||
// it clears the condition once when the node no longer fails alone, or is no longer one of the module's nodes. The first pass
|
||||
// after a start remembers nothing a previous process raised: for a module with a failed have on any node it clears the
|
||||
// condition of every node the presence bucket knows that does not fail alone (a clear of a condition not open is quiet at the
|
||||
// router). A condition the router did not take is said again at the next pass.
|
||||
// after a start remembers nothing a previous process raised: it clears, for every module, the condition of every node the
|
||||
// presence bucket knows that does not fail alone, since a node that recovered while no process watched leaves no failed have to
|
||||
// find it by (a clear of a condition not open is quiet at the router). A condition the router did not take is said again at the next pass.
|
||||
func (p *passer) sayNodeFailed(module, fp string, nodes []string, known assign.Nodes, out assign.Outcome, first bool) {
|
||||
if p.nodeFailed == nil {
|
||||
p.nodeFailed = map[string]string{}
|
||||
@@ -254,7 +254,7 @@ func (p *passer) sayNodeFailed(module, fp string, nodes []string, known assign.N
|
||||
look[node] = true
|
||||
}
|
||||
}
|
||||
if first && anyFailed(known, module) {
|
||||
if first {
|
||||
for node := range known.Online {
|
||||
look[node] = true
|
||||
}
|
||||
@@ -289,16 +289,6 @@ func (p *passer) sayNodeFailed(module, fp string, nodes []string, known assign.N
|
||||
}
|
||||
}
|
||||
|
||||
// anyFailed says whether any node's have of module says its health failed.
|
||||
func anyFailed(n assign.Nodes, module string) bool {
|
||||
for _, haves := range n.Haves {
|
||||
if h, ok := haves[module]; ok && h.Health == delivery.HealthFailed {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// neitherOne is a module assigned to a node that holds no want for it after a pass, and the rule holding its first want back.
|
||||
type neitherOne struct {
|
||||
node, module string
|
||||
|
||||
@@ -468,7 +468,7 @@ func TestThePassGathersTheModulesOnNeitherList(t *testing.T) {
|
||||
}
|
||||
}
|
||||
// D2: a node that leaves the module's nodes while it failed alone is cleared once; the first pass after a start clears every
|
||||
// node the presence bucket knows, for a module with a failed have, and nothing for one without.
|
||||
// node the presence bucket knows, for every module, failed have or not (a node that recovered unwatched leaves none).
|
||||
conds = nil
|
||||
p.sayNodeFailed("rofi", fpTest, []string{"shanks"}, assign.Nodes{}, assign.Outcome{NodeFailed: failing}, false)
|
||||
p.sayNodeFailed("rofi", fpTest, nil, assign.Nodes{}, assign.Outcome{}, false)
|
||||
@@ -484,7 +484,7 @@ func TestThePassGathersTheModulesOnNeitherList(t *testing.T) {
|
||||
keys []string
|
||||
}{
|
||||
{"a failed have", known, []string{"mesh-delivery-assigner.failed-alone.ace.rofi", "mesh-delivery-assigner.failed-alone.g14.rofi"}},
|
||||
{"no failed have", assign.Nodes{Online: known.Online}, nil},
|
||||
{"no failed have", assign.Nodes{Online: known.Online}, []string{"mesh-delivery-assigner.failed-alone.ace.rofi", "mesh-delivery-assigner.failed-alone.g14.rofi"}},
|
||||
} {
|
||||
conds = nil
|
||||
fresh := newPasser(buckets{}, time.Date(2026, 10, 26, 22, 0, 0, 0, time.UTC))
|
||||
|
||||
Reference in New Issue
Block a user