A seat is handed over as one act, and the holder is on record
`seat <name> --to <node>/<module>` makes one assignment the holder of a seat in the same write that removes the previous one. The row is new (migration 0039); without one, the resolver derives the holder as it always did — the sole eligible assignment, two refused — so nothing changes for a mesh that never hands a seat over. With one, the recorded assignment holds and any other whose module could hold the seat is eligible and silent: not refused, not holding. That is what lets the next holder run beside the current one until the switch (hq design 26, design 28 task 5.3, ADR 0131). Why: the controller finds its own bus through a seat, and the day that seat was left with nobody in it — because two eligible holders could not coexist and the old one's claim was taken away — the control plane looped for two hours while every service stayed up. A handover that is never empty in between is the fix, not a workaround for it. `CanHold` is the one judgement of whether a module may hold a seat — claims it at its scope, provides what it delivers, against the store's row — shared by registration and the handover so they cannot drift apart. The holding belongs to the assignment and goes when it does, so a seat never points at nothing running. Tests: the resolver with and without a record, on the same and another machine, under a former name; the store's row replaced not added, refused for an unassigned target, removed with its assignment; CanHold's four answers and that they follow the store. Full suite green against a real NATS and store.
This commit is contained in:
@@ -46,21 +46,39 @@ func TestTheSeatRefusesADifferentBusToo(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// The old broker no longer claims the seat: it is an ordinary provider of `amqp`
|
||||
// (novox/hq ADR 0119), so it can sit on the same mesh as the bus without contending for it.
|
||||
func TestTheAmqpBrokerDoesNotContendForTheSeat(t *testing.T) {
|
||||
// **The old broker claims the seat until the seat is handed over, and stands beside the new one
|
||||
// while it waits** (novox/hq ADR 0131, superseding the record this test used to pin). Whoever is on
|
||||
// record holds it; the other eligible claimant is neither refused nor holding. This is the shape the
|
||||
// handover needs: both brokers assigned, one bus, no moment with nobody in the seat.
|
||||
func TestTheOldBrokerStandsBesideTheNewOneUntilTheHandover(t *testing.T) {
|
||||
was := Seats()
|
||||
t.Cleanup(func() { UseSeats(was) })
|
||||
UseSeats([]Seat{{Name: "mesh-broker", Scope: ScopeMesh, Delivers: "mesh-bus", Decision: "test"}})
|
||||
|
||||
lavinmq := catalogueManifest(t, "lavinmq")
|
||||
for _, c := range lavinmq.Claims {
|
||||
if c.Name == "mesh-broker" {
|
||||
t.Fatal("the amqp broker still claims mesh-broker; it is a provider, not foundation")
|
||||
if !lavinmq.ClaimsSeat("mesh-broker") {
|
||||
t.Skip("the old broker no longer claims the seat: design 28 task 5.4 has removed it")
|
||||
}
|
||||
nats := catalogueManifest(t, "nats")
|
||||
onRecord := World{Holdings: []Held{{Claim: "mesh-broker", Scope: ScopeMesh,
|
||||
Node: "anchor", Module: "nats"}}}
|
||||
|
||||
// The same machine runs both. Without the record this is two holders and refused; with it, the
|
||||
// recorded one holds and the other is silent.
|
||||
anchor := workstation()
|
||||
anchor.Name = "anchor"
|
||||
got, err := Resolve(shelf(lavinmq, nats), []string{"lavinmq", "nats"}, anchor, onRecord)
|
||||
if err != nil {
|
||||
t.Fatalf("the old broker beside the recorded holder was refused: %v", err)
|
||||
}
|
||||
var holders []string
|
||||
for _, h := range got.Claims {
|
||||
if h.Claim == "mesh-broker" {
|
||||
holders = append(holders, h.Module)
|
||||
}
|
||||
}
|
||||
busHeld := World{Held: []Held{{Claim: "mesh-broker", Scope: ScopeMesh,
|
||||
Node: "anchor", Module: "nats"}}}
|
||||
other := workstation()
|
||||
other.Name = "laptop"
|
||||
if _, err := Resolve(shelf(lavinmq), []string{"lavinmq"}, other, busHeld); err != nil {
|
||||
t.Fatalf("the amqp broker was refused beside the mesh bus: %v", err)
|
||||
if len(holders) != 1 || holders[0] != "nats" {
|
||||
t.Fatalf("the seat is held by %v, not by the holder on record alone", holders)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user