The mesh's own roles carry a protocol, and the build branch retires
ADR 0121, first half. The `mesh-*` seats said who does a job and nothing about what may be said to them or by them, so the mesh had roles it could not describe. They take the same three fields a module's seat has now, and the machinery that already derives a work queue, a holder's worker and a permission set from a declared seat does it for these too. The build-machine role accepts a build and emits an outcome, so `mesh.build.request`, `mesh.control.built` and the BUILDS stream are gone. A work queue shared by several build machines is what a seat's `accepts` already is, and keeping a second mechanism for it was two places a permission could be wrong. The controller's own side of a seat is a named list rather than something derived: it is not a module and declares no `uses`, so which roles the mesh itself submits work to has to be stated — and stating it makes that question answerable. Two things this caught: **The followed event subjects were hard-coded and had just gone stale.** They were written out while the catalogue still spelled its events as the old bus's routing keys, so converting those (issue 127) turned the pair into a controller listening to a subject nothing publishes — the same fault as the issue, from the other side. They derive from the emitter and the event name now, through the same function the permission uses, so the two cannot drift apart. **A role's queue exists before its holder**, checked against a real server, and asserting twice changes nothing. Work queues until somebody arrives to do it, so assigning a build machine later flushes the backlog instead of having lost it.
This commit is contained in:
+17
-16
@@ -63,8 +63,10 @@ type Stream struct {
|
||||
func MeshStreams() []Stream {
|
||||
return []Stream{
|
||||
{
|
||||
Name: "CONTROL",
|
||||
Subjects: []string{"mesh.control.*.report", "mesh.control.enrol", "mesh.control.built"},
|
||||
Name: "CONTROL",
|
||||
// A build's outcome is no longer here: it is the build-machine seat's own event, so one
|
||||
// publish reaches whoever asked, the controller and the catalogue (novox/hq ADR 0121).
|
||||
Subjects: []string{"mesh.control.*.report", "mesh.control.enrol"},
|
||||
Retention: RetentionWorkQueue,
|
||||
Why: "the store-window guarantee (ADR 0083): the controller naks with a delay while its " +
|
||||
"store is away and the message is redelivered; nothing is dropped",
|
||||
@@ -76,12 +78,6 @@ func MeshStreams() []Stream {
|
||||
Why: "one declaration per node, always the newest; a node that sees sequence n refuses " +
|
||||
"n-1 by construction (issue 107)",
|
||||
},
|
||||
{
|
||||
Name: "BUILDS",
|
||||
Subjects: []string{"mesh.build.request"},
|
||||
Retention: RetentionWorkQueue,
|
||||
Why: "at least once, one builder at a time; a builder that dies mid-build has its message redelivered",
|
||||
},
|
||||
{
|
||||
Name: "EVENTS",
|
||||
// A seat's own events ride here too: they are 1:many like any event, and the
|
||||
@@ -167,15 +163,20 @@ const ControllerName = "controller"
|
||||
// ControllerFollows are the events the controller reacts to: the catalogue saying a module's
|
||||
// current version moved, and a catalogue that has just started saying it may have missed builds.
|
||||
//
|
||||
// **These carry the local names the manifests hold today**, which still spell an event the way a
|
||||
// routing key on the bus the mesh has does — `module.<module>.<verb>` rather than design 29's bare
|
||||
// verb — so the derived subject names the module twice. It is consistent, and it is what the
|
||||
// catalogue actually publishes, so it is what the controller must listen to. It changes when those
|
||||
// names are converted, and not before: a subscription written against the name design 29 specifies
|
||||
// would be a controller listening to a subject nothing publishes.
|
||||
// **Derived the same way a module's subscription is**, from the emitter and the bare local event
|
||||
// name, rather than written out. They were written out while the catalogue still spelled its events
|
||||
// as the old bus's routing keys, and the moment those were converted (novox/hq 04-ISSUES/127) a
|
||||
// hard-coded pair became a controller listening to a subject nothing publishes — the same fault, from
|
||||
// the other side. Deriving them means the conversion could not leave these behind.
|
||||
var ControllerFollows = []string{
|
||||
"mesh.mod.mesh-catalog.event.module.mesh-catalog.upgraded",
|
||||
"mesh.mod.mesh-catalog.event.module.mesh-catalog.catching-up",
|
||||
moduleEventSubject("mesh-catalog", "upgraded"),
|
||||
moduleEventSubject("mesh-catalog", "catching-up"),
|
||||
}
|
||||
|
||||
// moduleEventSubject is where one module's event lands. The same derivation PermissionsFor uses, so
|
||||
// what the controller subscribes and what the emitter is permitted to publish cannot drift apart.
|
||||
func moduleEventSubject(module, event string) string {
|
||||
return "mesh.mod." + module + ".event." + event
|
||||
}
|
||||
|
||||
// MeshConsumers is what the controller consumes, in the order a person reads it.
|
||||
|
||||
Reference in New Issue
Block a user