A wait the watchman mirrors keeps its earliest start while the same mark stands, so a key written again with new words does not start the bound again (ADR 0603 §8)
This commit is contained in:
@@ -476,6 +476,14 @@ func TestTheWatchmansFindings(t *testing.T) {
|
||||
if len(o.pulses) != 3 || len(o.findings) != 0 {
|
||||
t.Fatalf("pulses %v findings %v", o.pulses, o.findings)
|
||||
}
|
||||
// The keys are written again as their parts move on, with new words and a new time: the wait still began at t0.
|
||||
c.t = c.t.Add(20 * time.Minute)
|
||||
held2, _ := delivery.EncodeWant(delivery.Want{FP: fpOld, Self: true, Newest: fpNew, Rule: delivery.RuleCanary, Words: "the canary ace runs it, not healthy yet"})
|
||||
asked2, _ := provisions.Encode(provisions.Provision{Provision: "oidc", Consumer: provisions.End{Module: "photos", Node: "ace"},
|
||||
Provider: provisions.End{Module: "keycloak", Node: "novox"}, State: provisions.Asked, Why: "the provider is applying", At: c.t})
|
||||
w.Want("want.ace.web", held2, Put, c.t)
|
||||
w.Provision("ace.photos.oidc", asked2, Put)
|
||||
w.Build(bkey, queued, Put, c.t)
|
||||
for bucket, key := range waits {
|
||||
expire(w, c, pulseKeyOf(t, bucket, key), 31*time.Minute)
|
||||
}
|
||||
|
||||
@@ -102,13 +102,16 @@ func (w *Watchman) Want(key string, value []byte, op Op, at time.Time) {
|
||||
at = w.now()
|
||||
}
|
||||
w.held[key] = true
|
||||
w.mirrorWithin(w.stepBound, delivery.AssignerWantsBucket, key,
|
||||
w.mirrorKept(delivery.AssignerWantsBucket, key,
|
||||
describe("the hold on %s on %s at %s (rule %d) to end, bound %s: %s", module, node, shortFP(want.FP), want.Rule, w.stepBound, want.Words),
|
||||
"held|"+want.FP+"|"+want.Newest, at, 0)
|
||||
"held|"+want.FP+"|"+want.Newest, at)
|
||||
return
|
||||
}
|
||||
if w.held[key] {
|
||||
delete(w.held, key)
|
||||
if pk, err := delivery.PulseKey(delivery.AssignerWantsBucket, key); err == nil {
|
||||
delete(w.starts, pk)
|
||||
}
|
||||
w.stuckMoved(delivery.AssignerWantsBucket, key) // the hold ended: its finding is cleared
|
||||
}
|
||||
if w.have(node, module) == want.FP {
|
||||
@@ -156,8 +159,8 @@ func (w *Watchman) Build(key string, value []byte, op Op, at time.Time) {
|
||||
if at.IsZero() {
|
||||
at = w.now()
|
||||
}
|
||||
w.mirrorWithin(w.stepBound, delivery.BuilderBuildsBucket, key,
|
||||
describe("the package %s to be published before the build of %s at %s, bound %s", b.Waits, module, shortFP(fp), w.stepBound), b.Waits, at, 0)
|
||||
w.mirrorKept(delivery.BuilderBuildsBucket, key,
|
||||
describe("the package %s to be published before the build of %s at %s, bound %s", b.Waits, module, shortFP(fp), w.stepBound), b.Waits, at)
|
||||
}
|
||||
|
||||
// Have is a change of a key of the node-engine's have bucket: the fingerprint a node runs of a module. One that names the
|
||||
|
||||
@@ -632,7 +632,7 @@ func (w *Watchman) askedWait(key string, value []byte, op Op) {
|
||||
if p.Why != "" {
|
||||
words += ": " + p.Why
|
||||
}
|
||||
w.mirrorWithin(w.stepBound, bucket, key, words, "asked", since, 0)
|
||||
w.mirrorKept(bucket, key, words, "asked", since)
|
||||
}
|
||||
|
||||
func sortedKeys(m map[string]string) []string {
|
||||
|
||||
@@ -64,8 +64,10 @@ type Watchman struct {
|
||||
keptSince map[string]time.Time
|
||||
wants map[string]string // the fingerprint of each want that stands, by want key
|
||||
haves map[string]string // the fingerprint each node runs of a module, by have key
|
||||
held map[string]bool // each want key held by a rule (ADR 0603 §8), mirrored as the hold's wait
|
||||
bound time.Duration
|
||||
// starts is, by pulse key, the first start of a wait whose mark still stands (mirrorKept).
|
||||
starts map[string]startMark
|
||||
held map[string]bool // each want key held by a rule (ADR 0603 §8), mirrored as the hold's wait
|
||||
bound time.Duration
|
||||
// findings is every finding written, by key, as written; seededFindings those read at the start and not yet observed
|
||||
// again.
|
||||
findings map[string][]byte
|
||||
@@ -104,7 +106,7 @@ type Watchman struct {
|
||||
// New is a watchman writing to out, reading the time from now.
|
||||
func New(out Out, now func() time.Time) *Watchman {
|
||||
return &Watchman{out: out, now: now, counts: map[string]int{}, presence: map[string]presence{},
|
||||
pulses: map[string]*pulse{}, stuck: map[string]delivery.Stuck{}, wants: map[string]string{}, haves: map[string]string{}, held: map[string]bool{}, bound: delivery.PulseMoveBound, stepBound: StepBound,
|
||||
pulses: map[string]*pulse{}, stuck: map[string]delivery.Stuck{}, wants: map[string]string{}, haves: map[string]string{}, held: map[string]bool{}, starts: map[string]startMark{}, bound: delivery.PulseMoveBound, stepBound: StepBound,
|
||||
findings: map[string][]byte{}, seededFindings: map[string]bool{}, signals: map[string]signalDue{}, away: map[string]bool{},
|
||||
haveState: map[string]delivery.Have{}, unhealthy: map[string]int{}, advised: map[string]int{}, advisedSince: map[string]time.Time{},
|
||||
control: map[string]bool{}, failedSince: map[string]time.Time{}, provFailed: map[string]map[string]ProvReport{}, closures: map[string]map[string]time.Time{}, waiting: map[string]map[string]string{},
|
||||
@@ -162,6 +164,25 @@ func (w *Watchman) mirrorWithin(bound time.Duration, bucket, key, waited, head s
|
||||
w.pulses[pk] = &pulse{bucket: bucket, key: key, waited: waited, since: since, head: head, token: token}
|
||||
}
|
||||
|
||||
// startMark is when a wait began, for the mark that names it.
|
||||
type startMark struct {
|
||||
mark string
|
||||
since time.Time
|
||||
}
|
||||
|
||||
// mirrorKept is mirrorWithin for a wait that is the key's value standing as it is (ADR 0603 §8): while the same mark stands
|
||||
// (a provision asked, a want held at the same fingerprints, a build waiting for the same package), a rewrite of the key (new
|
||||
// words, a new time) does not start the bound again; the earliest start is kept. A different mark is a new wait.
|
||||
func (w *Watchman) mirrorKept(bucket, key, waited, mark string, since time.Time) {
|
||||
if pk, err := delivery.PulseKey(bucket, key); err == nil {
|
||||
if cur, ok := w.starts[pk]; ok && cur.mark == mark && cur.since.Before(since) {
|
||||
since = cur.since
|
||||
}
|
||||
w.starts[pk] = startMark{mark: mark, since: since}
|
||||
}
|
||||
w.mirrorWithin(w.stepBound, bucket, key, waited, mark, since, 0)
|
||||
}
|
||||
|
||||
func (w *Watchman) deletePulse(pk string) {
|
||||
delete(w.pulses, pk)
|
||||
if err := w.out.DeletePulse(pk); err != nil {
|
||||
@@ -176,6 +197,7 @@ func (w *Watchman) moved(bucket, key string) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
delete(w.starts, pk)
|
||||
if _, ok := w.pulses[pk]; ok {
|
||||
w.deletePulse(pk)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user