Measure a repository's last check time from its newest verdict (ADR 0505 §4)

This commit is contained in:
2026-10-22 14:13:18 +02:00
parent b5908b486e
commit 5ddc3ff312
2 changed files with 60 additions and 0 deletions
@@ -39,3 +39,29 @@ func TestTheBoundsAreSettingsWithTheirDefaults(t *testing.T) {
t.Fatalf("a bound of zero minutes was taken")
}
}
// ADR 0505 §4: a repository's last measured check time is its newest verdict's (`took`, as mesh-controller
// cmd/mesh-builder main.go writes it: a duration rounded to the second); none, and the floor alone holds.
func TestTheLastMeasuredCheckTimeIsTheNewestVerdictsOfItsRepository(t *testing.T) {
h := &Holder{}
h.init()
at := time.Date(2026, 10, 22, 10, 0, 0, 0, time.UTC)
h.deliveries["novox/mesh-catalog@a"] = &Delivery{ID: "novox/mesh-catalog@a", Repository: "novox/mesh-catalog",
Check: &Verdict{At: at, Took: "4m0s"}}
h.deliveries["novox/mesh-catalog@b"] = &Delivery{ID: "novox/mesh-catalog@b", Repository: "novox/mesh-catalog",
Check: &Verdict{At: at.Add(time.Hour), Took: "7m30s"}}
h.deliveries["novox/hq@c"] = &Delivery{ID: "novox/hq@c", Repository: "novox/hq",
Check: &Verdict{At: at.Add(2 * time.Hour), Took: "1m0s"}}
if got := h.lastCheckTime("novox/mesh-catalog"); got != 7*time.Minute+30*time.Second {
t.Fatalf("the newer of two: %s", got)
}
if got := h.answeredRefusalBound("novox/mesh-catalog"); got != 15*time.Minute {
t.Fatalf("twice 7m30s: %s", got)
}
if got := h.answeredRefusalBound("novox/hq"); got != 10*time.Minute {
t.Fatalf("twice one minute is under the floor: %s", got)
}
if got := h.answeredRefusalBound("novox/mesh-sdk"); got != 10*time.Minute {
t.Fatalf("no verdict: %s", got)
}
}
@@ -0,0 +1,34 @@
package main
import "time"
// lastCheckTime is how long the newest answered check of a repository ran, as its verdict says it (`took`): the
// repository's last measured check time (novox/hq ADR 0505 §4). Zero when no verdict of the repository says it.
// Under the lock.
func (h *Holder) lastCheckTime(repository string) time.Duration {
var newest *Verdict
var took time.Duration
for _, d := range h.deliveries {
v := d.Check
if d.Repository != repository || v == nil || v.Took == "" {
continue
}
t, err := time.ParseDuration(v.Took)
if err != nil || t <= 0 {
continue
}
if newest == nil || v.At.After(newest.At) {
newest, took = v, t
}
}
return took
}
// answeredRefusalBound is how long a refusal the gate is already answering waits before it is said as stalled: twice
// the repository's last measured check time, at least the floor (ADR 0505 §4). Under the lock.
func (h *Holder) answeredRefusalBound(repository string) time.Duration {
if b := 2 * h.lastCheckTime(repository); b > h.refusalFloor() {
return b
}
return h.refusalFloor()
}