The module offering bus-state never waits on bus state itself, and an offline node's build offers nothing (ADR 0614 §5; issue 774)
A bus module that both offers and asks bus state waited on itself for good at its first such build; it now waits on nobody for it, as the graph and catalogue.Awaited leave a module's own provision out. Claude-Session: https://claude.ai/code/session_01JG73KG7AfSdh6FP8VrBqCn
This commit is contained in:
@@ -1072,4 +1072,14 @@ func aWantWaitsOnTheVerbEdgesTheGraphKeeps(t *testing.T) {
|
||||
t.Errorf("served(%s) = %v, want %v: the running server's manifest serves w alone, late's is not read", v, served(v), want)
|
||||
}
|
||||
}
|
||||
// ADR 0614 §5: bus-state counts as offered only from a healthy build on a node present; the bus module's build on an
|
||||
// offline node offers nothing, and one whose manifest is not read counts its trunk manifest's offer.
|
||||
bus := map[string]catalogue.Manifest{"bus": {Module: "bus", Provides: []catalogue.Offer{{Name: graph.BusState, Scope: catalogue.ScopeMesh}}}}
|
||||
for _, online := range []bool{false, true} {
|
||||
offering := p.offering(context.Background(), get, bus, assign.Nodes{Online: map[string]bool{"n2": online},
|
||||
Haves: map[string]map[string]delivery.Have{"n2": {"bus": at(fp("2"))}}})
|
||||
if offering(graph.BusState) != online {
|
||||
t.Errorf("with the bus module's node online %v, bus-state offered %v", online, offering(graph.BusState))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,9 +27,11 @@ func (m Module) verbWaiting(node string) (string, bool) {
|
||||
// bus-state entry, as the module graph reads it) and no build whose manifest offers bus-state runs healthy on a node
|
||||
// present. The provision bus-state is answered with no credential of a consumer's own, so ADR 0603 §5 counts the
|
||||
// provider's own have and no provisioner key is waited for, handed or not. Nil Offering (nothing read of what runs) waits
|
||||
// for none. It holds under the provisions' rule, its words naming bus state (graph.BusStateWaitWords).
|
||||
// for none, and neither does a module that offers bus-state itself. It holds under the provisions' rule, its words naming bus state (graph.BusStateWaitWords).
|
||||
func (m Module) busStateWaiting(node string) (string, bool) {
|
||||
if len(m.Manifest.BusState) == 0 || m.Offering == nil || m.Offering(graph.BusState) {
|
||||
if len(m.Manifest.BusState) == 0 || m.Offering == nil || m.Offering(graph.BusState) ||
|
||||
slices.Contains(m.Manifest.Offers(), graph.BusState) { // the bus module offering it waits on nobody for it
|
||||
|
||||
return "", false
|
||||
}
|
||||
return graph.BusStateWaitWords(m.Name, node), true
|
||||
|
||||
@@ -161,6 +161,7 @@ func TestEachRuleHoldsTheWantBack(t *testing.T) {
|
||||
// ADR 0614 §5: a module asking bus state is held while no build offering bus-state runs, and moves once one does.
|
||||
{"bus state no running build offers", nil, nil, false, graph.BusState},
|
||||
{"bus state a running build offers", nil, []string{graph.BusState}, false, ""},
|
||||
{"bus state its own module offers", nil, nil, false, ""},
|
||||
} {
|
||||
m, n := ready()
|
||||
m.Invokes = c.invokes
|
||||
@@ -170,6 +171,9 @@ func TestEachRuleHoldsTheWantBack(t *testing.T) {
|
||||
if strings.HasPrefix(c.name, "bus state") {
|
||||
m.Manifest.BusState = []catalogue.BusStateEntry{{Name: "cache", Storage: "key-value"}}
|
||||
m.Offering = func(p string) bool { return slices.Contains(c.served, p) }
|
||||
if c.name == "bus state its own module offers" {
|
||||
m.Manifest.Provides = []catalogue.Offer{{Name: graph.BusState, Scope: catalogue.ScopeMesh}}
|
||||
}
|
||||
}
|
||||
words := graph.VerbWaitWords(c.holds, "mail", "g14")
|
||||
if c.holds == graph.BusState {
|
||||
|
||||
Reference in New Issue
Block a user