Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c3f44a526 |
@@ -5,7 +5,6 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/novox/mesh-controller/internal/broker"
|
"github.com/novox/mesh-controller/internal/broker"
|
||||||
"github.com/novox/mesh-controller/internal/catalogue"
|
|
||||||
"github.com/novox/mesh-controller/internal/link"
|
"github.com/novox/mesh-controller/internal/link"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -28,17 +27,4 @@ func TestTheFactsTheGrantPermitsAreTheFactsTheMeshStates(t *testing.T) {
|
|||||||
if len(broker.ControllerStates) != 3 {
|
if len(broker.ControllerStates) != 3 {
|
||||||
t.Errorf("the grant permits %v, which is more than the mesh states", broker.ControllerStates)
|
t.Errorf("the grant permits %v, which is more than the mesh states", broker.ControllerStates)
|
||||||
}
|
}
|
||||||
// **And the seat says it.** A seat carries the protocol of its role (novox/hq ADR 0129), so the
|
|
||||||
// facts the control plane states are the seat's `emits` — which is what lets anything else declare
|
|
||||||
// that it consumes them, and what the subject-agreement check reads to know they have an owner.
|
|
||||||
var declared []string
|
|
||||||
for _, seat := range catalogue.SeatsWithAProtocol() {
|
|
||||||
if seat.Name == broker.ControllerSeat {
|
|
||||||
declared = seat.Emits
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !slices.Equal(declared, broker.ControllerStates) {
|
|
||||||
t.Errorf("the %s seat emits %v and the grant permits %v", broker.ControllerSeat,
|
|
||||||
declared, broker.ControllerStates)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ func (r Registry) has(ctx context.Context, url string, accept ...string) (bool,
|
|||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
for _, media := range accept {
|
for _, media := range accept {
|
||||||
request.Header.Set("Accept", media)
|
request.Header.Add("Accept", media)
|
||||||
}
|
}
|
||||||
response, err := r.client().Do(request)
|
response, err := r.client().Do(request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -48,11 +48,7 @@ type Seat struct {
|
|||||||
//
|
//
|
||||||
// In the order a person reads it: the mesh's own, then a node's.
|
// In the order a person reads it: the mesh's own, then a node's.
|
||||||
var defaultSeats = []Seat{
|
var defaultSeats = []Seat{
|
||||||
// The control plane states what it did under the seat it holds (novox/hq ADR 0134): a role's
|
{Name: "mesh-controller", Scope: ScopeMesh, Decision: "novox/hq ADR 0079"},
|
||||||
// events belong to the role, so they keep their address while the holder is replaced. No accepts,
|
|
||||||
// so no work queue is raised for it — only what its holder may say.
|
|
||||||
{Name: "mesh-controller", Scope: ScopeMesh, Decision: "novox/hq ADR 0079",
|
|
||||||
Emits: []string{"applied", "refused", "built-before"}},
|
|
||||||
{Name: "mesh-store", Scope: ScopeMesh, Delivers: "postgres-database", Decision: "novox/hq ADR 0079"},
|
{Name: "mesh-store", Scope: ScopeMesh, Delivers: "postgres-database", Decision: "novox/hq ADR 0079"},
|
||||||
// **Delivers the mesh's own bus, not `amqp`.** Those were the same word until
|
// **Delivers the mesh's own bus, not `amqp`.** Those were the same word until
|
||||||
// ADR 0127 separated them: `amqp` is a backing service a module may require, and this seat is
|
// ADR 0127 separated them: `amqp` is a backing service a module may require, and this seat is
|
||||||
|
|||||||
+9
-13
@@ -476,7 +476,15 @@ func (s *Server) catchingUp(ctx context.Context, m Control) {
|
|||||||
// module's event from a module called "control-plane", which does not exist — so the
|
// module's event from a module called "control-plane", which does not exist — so the
|
||||||
// controller's own account refused it, every catalogue that asked what it missed was
|
// controller's own account refused it, every catalogue that asked what it missed was
|
||||||
// answered with nothing, and its graph kept the gap (found 2026-09-28).
|
// answered with nothing, and its graph kept the gap (found 2026-09-28).
|
||||||
if err := s.bus.PublishSeatEvent(ctx, MeshControllerSeat, KeyBuiltBefore, replayed(a)); err != nil {
|
body, err := json.Marshal(a)
|
||||||
|
if err != nil {
|
||||||
|
// A body that cannot be written is this program's fault, not the bus's, and publishing
|
||||||
|
// an empty one would put a fact on the mesh that says nothing.
|
||||||
|
s.log.Printf("cannot re-announce %s at %s: %v", a.Module, short(a.Commit), err)
|
||||||
|
_ = m.Took()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := s.bus.PublishSeatEvent(ctx, MeshControllerSeat, KeyBuiltBefore, body); err != nil {
|
||||||
// Said and abandoned rather than retried: the catalogue asks again every time it
|
// Said and abandoned rather than retried: the catalogue asks again every time it
|
||||||
// starts, and half a graph delivered twice is no better than half delivered once.
|
// starts, and half a graph delivered twice is no better than half delivered once.
|
||||||
s.log.Printf("replaying %s at %s failed, and the rest is abandoned: %v",
|
s.log.Printf("replaying %s at %s failed, and the rest is abandoned: %v",
|
||||||
@@ -601,15 +609,3 @@ func (s *Server) saysWhatItDid(ctx context.Context, report Report) {
|
|||||||
s.log.Printf("could not say that %s %s: %v", report.Node, event, err)
|
s.log.Printf("could not say that %s %s: %v", report.Node, event, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// replayed is one announcement as the control plane states it. The same body the build machine's
|
|
||||||
// outcome carries, because what the catalogue does with it is the same.
|
|
||||||
func replayed(a Announcement) []byte {
|
|
||||||
raw, err := json.Marshal(a)
|
|
||||||
if err != nil {
|
|
||||||
// A body that cannot be marshalled is a programming error, not a bus failure, and an empty
|
|
||||||
// one is refused by the reader rather than silently taken as an announcement of nothing.
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return raw
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user