2536 reads of mesh-controller.lease were refused on 2026-10-30 (mesh-vault, mesh-grants, the assigner, artifact-store-tools, the watchman, mesh-config). The controller composed the bus's users with its own copy of a reader-less judgement (internal/broker ReadsAnnounced), which knows no named readers: the lease is announced readable by nobody and read by the parts named for it (ADR 0547 clause 9, ADR 0561 §3). The copy is deleted; BusRecords judges each read for its module with buscompose.ReadsAnnouncedBy. Each refusal was also printed on every composition, about 420 times a read; it is now said once per process. mesh-config's read of the lease stays refused: it reads the lease for its take-over (hand-back ends at the lease write, ADR 0561 §3) and is not among the named readers. That is mesh-sdk's NamedReaders, routed to the lead. Quick fix: mark the lease readable in the controller's announcement (tried and reverted: it would open the lease to every module and contradict ADR 0561 §3). Thorough fix: one judgement, the SDK's, for every composer. Chose thorough. Research 072 piece: 03-domains, mesh-grants (bus membership and grants leave the controller): the controller composes reads with the same SDK function the grants part uses.
66 lines
2.7 KiB
Go
66 lines
2.7 KiB
Go
package broker
|
|
|
|
import (
|
|
"sort"
|
|
"strings"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/announce"
|
|
)
|
|
|
|
// Who may read a module's state is what the module announced (novox/hq ADR 0495 clauses 2 and 3, ADR 0513 §3; issue
|
|
// 1790). A module says on the bus which states it keeps and which others may read (announce.Subject); the controller
|
|
// keeps the last word of each (announce.KeptBucket) and grants a reader's `reads: <owner>.<name>` only when the owner
|
|
// announced that state readable. An owner that has announced nothing yet is read as before, from the reader's `reads`
|
|
// (the transition, until every module announces), and is named as not yet announced.
|
|
|
|
// StatesAnnouncedBucket is the controller's bucket of the last announcement of each module (announce.KeptBucket).
|
|
const StatesAnnouncedBucket = announce.KeptBucket
|
|
|
|
// controllerReadable are the controller's states others may read: the record mirrors (the packages each node declares
|
|
// among them, which the pacman module reads, ADR 0507 §5), the chain's buckets, and the grants issued and the
|
|
// compositions' digests, which the assigner reads (ADR 0528 clause 2, ADR 0539 clause 6).
|
|
var controllerReadable = []string{MirrorAssignments, MirrorDeclaredConfig, MirrorPredefined, ChainBuilds, ChainRollouts,
|
|
MirrorDeclaredPackages, ControllerGrants, ControllerComposed}
|
|
|
|
// ControllerAnnouncement is what the controller announces it keeps (ADR 0495 clause 2): every bucket of its own by its local
|
|
// name, the ones others may read marked readable. It announces itself, as any module does from its code.
|
|
func ControllerAnnouncement(node string) announce.States {
|
|
s := announce.States{Module: ControllerSeat, Node: node}
|
|
readable := map[string]bool{}
|
|
for _, n := range controllerReadable {
|
|
readable[n] = true
|
|
}
|
|
for _, bucket := range ControllerBuckets() {
|
|
local, mine := strings.CutPrefix(bucket, ControllerSeat+"_")
|
|
if !mine {
|
|
continue
|
|
}
|
|
s.States = append(s.States, announce.State{Name: local, Readable: readable[local]})
|
|
}
|
|
sort.Slice(s.States, func(i, j int) bool { return s.States[i].Name < s.States[j].Name })
|
|
return s
|
|
}
|
|
|
|
// NotAnnounced are the owners some module reads the state of and that have announced nothing yet, sorted: read from the
|
|
// readers' `reads` as before, until they announce.
|
|
func NotAnnounced(r Records) []string {
|
|
seen := map[string]bool{}
|
|
var out []string
|
|
for _, ds := range r.Assigned {
|
|
for _, d := range ds {
|
|
for _, read := range append(append([]string(nil), d.Reads...), d.ReadsRefused...) {
|
|
owner, _, ok := strings.Cut(read, ".")
|
|
if !ok || seen[owner] {
|
|
continue
|
|
}
|
|
if _, said := r.Announced[owner]; !said {
|
|
seen[owner] = true
|
|
out = append(out, owner)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
sort.Strings(out)
|
|
return out
|
|
}
|