mesh-healers: attempts, would, the healer-acted event and its findings are the seats' contract types (B5d; ADR 0634 §1, §4; issue 1966)
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
This commit is contained in:
@@ -24,9 +24,11 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient"
|
||||
meshconditions "git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshconditions"
|
||||
meshhealers "git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshhealers"
|
||||
stdio "git.novox.be/novox/mesh-sdk/go"
|
||||
"git.novox.be/novox/mesh-sdk/go/handacts"
|
||||
"git.novox.be/novox/mesh-sdk/go/health"
|
||||
)
|
||||
|
||||
// Module and Seat are this module and the seat it holds once for the mesh.
|
||||
@@ -37,11 +39,11 @@ const (
|
||||
|
||||
// The states it keeps and reads, and the event it says.
|
||||
const (
|
||||
AttemptsState = health.AttemptsState
|
||||
WouldState = health.WouldState
|
||||
FindingsState = health.FindingsState
|
||||
AttemptsState = meshhealers.StateAttempts
|
||||
WouldState = meshhealers.StateWould
|
||||
FindingsState = meshconditions.StateFindings
|
||||
ConditionsRead = "mesh-conditions.conditions"
|
||||
ActedEvent = health.EventHealerActed
|
||||
ActedEvent = meshhealers.EventHealerActed
|
||||
// ActedSubject is where the seat says it, which its consumers hear (catalogue.SeatSays).
|
||||
ActedSubject = "mesh.seat." + Seat + ".event." + ActedEvent
|
||||
// RecordedEvent is the hand-act log's seat event, each act recorded there (ADR 0565 §11).
|
||||
@@ -59,10 +61,10 @@ const (
|
||||
|
||||
// The outcomes an attempt has.
|
||||
const (
|
||||
OutcomeActing = health.OutcomeActing
|
||||
OutcomeActed = health.OutcomeActed
|
||||
OutcomeFailed = health.OutcomeFailed
|
||||
OutcomeEscalated = health.OutcomeEscalated
|
||||
OutcomeActing = meshhealers.HealerActedEventOutcomeActing
|
||||
OutcomeActed = meshhealers.HealerActedEventOutcomeActed
|
||||
OutcomeFailed = meshhealers.HealerActedEventOutcomeFailed
|
||||
OutcomeEscalated = meshhealers.HealerActedEventOutcomeEscalated
|
||||
)
|
||||
|
||||
// Store is the bus's buckets as this module reaches them, through its runtime. CreateTTL writes a key only when it has
|
||||
@@ -113,9 +115,9 @@ func (c Condition) Escalated() bool { return c.Resolver == "operator" && len(c.T
|
||||
// (one key per healer and condition, `<healer>.<condition key>`, its newest), and the body of healer-acted,
|
||||
// epoch left out (ADR 0564 Limits 10).
|
||||
type (
|
||||
Attempt = health.Attempt
|
||||
Would = health.Would
|
||||
Acted = health.HealerActed
|
||||
Attempt = meshhealers.AttemptsByAttemptValue
|
||||
Would = meshhealers.WouldByWouldValue
|
||||
Acted = meshhealers.HealerActedEvent
|
||||
)
|
||||
|
||||
// Healer is one row of the registry.
|
||||
@@ -481,7 +483,7 @@ func (h *Healers) brakeHolds(acts []Attempt, now time.Time) (bool, string) {
|
||||
return false, said
|
||||
}
|
||||
|
||||
var brakeKey = health.Key(ScopeMesh, "healers", "braked")
|
||||
var brakeKey = meshconditionsclient.Key(ScopeMesh, "healers", "braked")
|
||||
|
||||
// brakeFinding is the brake, as the urgent finding that says it.
|
||||
func brakeFinding(acts []Attempt, said string) Observation {
|
||||
@@ -519,7 +521,7 @@ func (h *Healers) blind(err error) {
|
||||
// no longer sees (ADR 0564 §2).
|
||||
func (h *Healers) see(source string, found []Observation) {
|
||||
now := h.Now()
|
||||
want := map[string]health.Finding{}
|
||||
want := map[string]meshconditions.FindingsByKeyValue{}
|
||||
for _, o := range found {
|
||||
o.Source = source
|
||||
want[o.Key()] = o.Finding("", now)
|
||||
@@ -534,7 +536,8 @@ func (h *Healers) see(source string, found []Observation) {
|
||||
if err != nil || !found {
|
||||
continue
|
||||
}
|
||||
was, err := health.DecodeFinding(raw)
|
||||
var was meshconditions.FindingsByKeyValue
|
||||
err = json.Unmarshal(raw, &was)
|
||||
if err != nil || was.Source != source {
|
||||
continue
|
||||
}
|
||||
@@ -549,7 +552,7 @@ func (h *Healers) see(source string, found []Observation) {
|
||||
}
|
||||
}
|
||||
for k, f := range want {
|
||||
raw, err := health.EncodeFinding(f)
|
||||
raw, err := json.Marshal(f)
|
||||
if err == nil {
|
||||
err = h.Store.Put(FindingsState, k, json.RawMessage(raw))
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
meshconditions "git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshconditions"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
@@ -12,7 +13,6 @@ import (
|
||||
"time"
|
||||
|
||||
"git.novox.be/novox/mesh-sdk/go/handacts"
|
||||
"git.novox.be/novox/mesh-sdk/go/health"
|
||||
)
|
||||
|
||||
type memStore struct {
|
||||
@@ -286,7 +286,8 @@ func TestBudgetSettleEscalationAndBrake(t *testing.T) {
|
||||
t.Errorf("past the brake: %q, asked %v", said, b.asked)
|
||||
}
|
||||
raw, braked, _ := b.store.Get(FindingsState, brakeKey)
|
||||
f, _ := health.DecodeFinding(raw)
|
||||
var f meshconditions.FindingsByKeyValue
|
||||
_ = json.Unmarshal(raw, &f)
|
||||
if !braked || f.Severity != Urgent || f.Kind != "healers-braked" || f.Observer != Module {
|
||||
t.Errorf("the brake is written as %s", raw)
|
||||
}
|
||||
|
||||
@@ -1,33 +1,34 @@
|
||||
package main
|
||||
|
||||
// What the healers observe of themselves, and the finding it is written as (novox/hq ADR 0564 §2): the brake, their
|
||||
// blindness and S15, each written into the bucket `findings` as mesh-sdk's health.Finding, whose key is the
|
||||
// blindness and S15, each written into the bucket `findings` as the seat mesh-conditions' finding, whose key is the
|
||||
// controller's key for the same condition.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"git.novox.be/novox/mesh-sdk/go/health"
|
||||
"git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient"
|
||||
meshconditions "git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshconditions"
|
||||
)
|
||||
|
||||
// The severities and scopes, as mesh-sdk's health names them.
|
||||
const (
|
||||
Urgent = health.Urgent
|
||||
Warning = health.Warning
|
||||
ScopeProbe = health.ScopeProbe
|
||||
ScopeMesh = health.ScopeMesh
|
||||
Urgent = meshconditionsclient.Urgent
|
||||
Warning = meshconditionsclient.Warning
|
||||
ScopeProbe = meshconditionsclient.ScopeProbe
|
||||
ScopeMesh = meshconditionsclient.ScopeMesh
|
||||
)
|
||||
|
||||
// Subject is what a finding is about.
|
||||
type Subject = health.Subject
|
||||
type Subject = meshconditions.Subject
|
||||
|
||||
// Observation is one thing a probe sees wrong now.
|
||||
type Observation struct {
|
||||
Kind string
|
||||
Ref string
|
||||
Subject Subject
|
||||
Severity health.Severity
|
||||
Severity string
|
||||
Summary string
|
||||
Said string
|
||||
Headline string
|
||||
@@ -44,14 +45,14 @@ func (o Observation) Key() string {
|
||||
if token == "" {
|
||||
token = o.Kind
|
||||
}
|
||||
return health.Key(o.Subject.Scope, o.Subject.ID, token)
|
||||
return meshconditionsclient.Key(o.Subject.Scope, o.Subject.ID, token)
|
||||
}
|
||||
|
||||
// Finding is the observation as written by run at, its evidence the one line it said.
|
||||
func (o Observation) Finding(run string, at time.Time) health.Finding {
|
||||
f := health.Finding{Key: o.Key(), Kind: o.Kind, Subject: o.Subject, Severity: o.Severity, Summary: o.Summary,
|
||||
func (o Observation) Finding(run string, at time.Time) meshconditions.FindingsByKeyValue {
|
||||
f := meshconditions.FindingsByKeyValue{V: meshconditionsclient.FindingVersion, Key: o.Key(), Kind: o.Kind, Subject: o.Subject, Severity: o.Severity, Summary: o.Summary,
|
||||
Headline: o.Headline, Explanation: o.Explanation, Resolved: o.Resolved, Needs: o.Needs, Source: o.Source,
|
||||
Observer: Module, Run: run, At: at.UTC(), Evidence: []health.Evidence{}}
|
||||
Observer: Module, Run: run, At: at.UTC(), Evidence: []meshconditions.Evidence{}}
|
||||
if o.Ref != "" && o.Ref != o.Kind {
|
||||
f.Ref = o.Ref
|
||||
}
|
||||
@@ -59,17 +60,17 @@ func (o Observation) Finding(run string, at time.Time) health.Finding {
|
||||
if said == "" {
|
||||
said = o.Summary
|
||||
}
|
||||
f.Evidence = append(f.Evidence, health.Evidence{At: at.UTC(), Said: said})
|
||||
f.Evidence = append(f.Evidence, meshconditions.Evidence{At: at.UTC(), Said: said})
|
||||
return f
|
||||
}
|
||||
|
||||
// says is what a finding says, its times and the run that wrote it aside: two findings that say the same are one write
|
||||
// (ADR 0289 §1).
|
||||
func says(f health.Finding) string {
|
||||
func says(f meshconditions.FindingsByKeyValue) string {
|
||||
f.At, f.Run, f.V = time.Time{}, "", 0
|
||||
ev := make([]health.Evidence, len(f.Evidence))
|
||||
ev := make([]meshconditions.Evidence, len(f.Evidence))
|
||||
for i, e := range f.Evidence {
|
||||
ev[i] = health.Evidence{Said: e.Said}
|
||||
ev[i] = meshconditions.Evidence{Said: e.Said}
|
||||
}
|
||||
f.Evidence = ev
|
||||
raw, _ := json.Marshal(f)
|
||||
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -27,7 +28,6 @@ import (
|
||||
"github.com/nats-io/nats.go"
|
||||
"github.com/nats-io/nats.go/jetstream"
|
||||
|
||||
"git.novox.be/novox/mesh-sdk/go/health"
|
||||
"git.novox.be/novox/mesh-sdk/go/testbus"
|
||||
)
|
||||
|
||||
@@ -312,7 +312,7 @@ func eventually(t *testing.T, what string, ok func() bool) {
|
||||
func raised(key, module string) []byte {
|
||||
raw, _ := json.Marshal(map[string]any{"key": key, "kind": "consumer-lost", "severity": "warning", "resolver": "self",
|
||||
"subject": map[string]any{"scope": "bus", "id": "EVENTS." + module}, "event": "condition-raised",
|
||||
"show": health.ShowKeeper(key)})
|
||||
"show": meshconditionsclient.ShowKeeper(key)})
|
||||
return raw
|
||||
}
|
||||
|
||||
|
||||
@@ -21,3 +21,6 @@ require (
|
||||
golang.org/x/sys v0.48.0 // indirect
|
||||
golang.org/x/time v0.16.0 // indirect
|
||||
)
|
||||
require git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient v0.0.0-00010101000000-000000000000
|
||||
require git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshconditions v0.0.0-00010101000000-000000000000
|
||||
require git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshhealers v0.0.0-00010101000000-000000000000
|
||||
|
||||
Reference in New Issue
Block a user