Stop hearing the retired build seats' events in gitea and the catalogue module, so no manifest consumes a seat nothing claims once node-build-agent goes (issue 1887 E2 with A9)
This commit is contained in:
+3
-21
@@ -20,8 +20,8 @@
|
||||
// writes it (check.ts; ADR 0521, R4e finding R2-1). No tool writes mesh/check (finding K1), and no event: the watch hands
|
||||
// over the latest value of every key whenever this module starts.
|
||||
//
|
||||
// Consumes node-build-agent.started — a build machine took an ask — and says, on the head a pending check is of,
|
||||
// which machine builds it since when (novox/hq issue 446). This module is the one writer of mesh/merge-gate.
|
||||
// This module is the one writer of mesh/merge-gate. It hears no build seat's event: since R4g a check's steps are asks
|
||||
// on the build seats' streams, whose backlog the delivery view shows (novox/hq ADR 0525 §9; issue 1887).
|
||||
//
|
||||
// **A trunk's move puts every open verdict into it out of date** (novox/hq ADR 0323 §4, trunk.ts): each pass reads the
|
||||
// head of every trunk an open pull request merges into, and when one moved, the merge check statuses of every open pull
|
||||
@@ -53,7 +53,7 @@ import { mergeTool } from "./merge.js";
|
||||
import { GiteaAdmin, GiteaClient, movedSince } from "./client.js";
|
||||
import { CHECK_CONTEXT, CHECK_STATUS, REPO_CHECK_CONTEXT, commentFor, composedGate, groupGateStatus, headsToAnnounce, maintained,
|
||||
requiredOf, statusesFor, writesGate, type Announced, type Checked, repoCheckFacts, reposToLook } from "./pulls.js";
|
||||
import { GateWriter, clonedAs, type BuildStarted } from "./gate.js";
|
||||
import { GateWriter } from "./gate.js";
|
||||
import { HOOK_PATH, HOOK_PORT, Pace, claimHead, ensureSystemHook, eventsTool, keptSecret, receiver, type ForgeEvent } from "./webhook.js";
|
||||
import { keepSiblings, noteComposed, noteVerdict, readSiblings, siblingsFile, siblingsOf, weighSiblings } from "./siblings.js";
|
||||
import { bindInBackground } from "./bind.js";
|
||||
@@ -504,23 +504,6 @@ registerModuleTools("gitea", () => [eventsTool(pace), ...(gitea ? [commitStatusT
|
||||
gates,
|
||||
}), mergeTool(gitea, { gates })] : [])]);
|
||||
|
||||
// **A build machine took an ask** (the build seat's `started`, novox/hq ADR 0157): said on the head it checks, when
|
||||
// the head is an open pull request's this module announced. Any other build — a branch, a merge's — says nothing.
|
||||
async function buildStarted(event: { body: unknown }): Promise<void> {
|
||||
const b = (event.body ?? {}) as BuildStarted;
|
||||
const ref = String(b.ref ?? "").toLowerCase();
|
||||
if (!/^[0-9a-f]{40}$/.test(ref)) return;
|
||||
for (const [key, sha] of Object.entries(heads)) {
|
||||
if (sha.toLowerCase() !== ref) continue;
|
||||
const [owner, rest] = key.split("/");
|
||||
const repo = rest?.split("#")[0] ?? "";
|
||||
if (owner && repo && clonedAs(b.repository, owner, repo)) {
|
||||
await gates.started(owner, repo, sha, b);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** What the forge's event asks of the announcer at once (issue 729): a new head is announced, and a merge. */
|
||||
async function actOn(client: GiteaClient, event: ForgeEvent): Promise<void> {
|
||||
const b = event.body as { owner?: string; repo?: string; number?: number };
|
||||
@@ -628,7 +611,6 @@ if (gitea) {
|
||||
}
|
||||
return setVerdict(client, event);
|
||||
})],
|
||||
["node-build-agent.started", () => on("node-build-agent.started", buildStarted)],
|
||||
], () => console.log("[gitea] watching for new repositories and merged pull requests"));
|
||||
// The checker's mesh/check, from its owed state (check.ts; ADR 0521): a read not granted yet is said once and asked again,
|
||||
// apart from the binds above, so neither waits for the other.
|
||||
|
||||
@@ -86,8 +86,7 @@
|
||||
"forge.other"
|
||||
],
|
||||
"consumes": [
|
||||
"mesh-controller.checked",
|
||||
"node-build-agent.started"
|
||||
"mesh-controller.checked"
|
||||
],
|
||||
"listens": [
|
||||
{
|
||||
|
||||
@@ -47,12 +47,8 @@ export interface Built {
|
||||
|
||||
/** The events a build outcome reaches this module on: the build seat's, as it happens, and the control plane's replay. */
|
||||
export const BUILD_EVENTS = [
|
||||
// **The build seat that builds now** (novox/hq ADR 0190). Until issue 712 the catalogue heard only the
|
||||
// retired seat below, so every build after the handover reached the graph only through the replay this
|
||||
// module asks for when it starts: a merge built and pushed stayed out of the catalogue until its next start.
|
||||
"node-build-agent.built",
|
||||
// The retired build role, while a machine still serves it (ADR 0190's handover). Goes with the seat row.
|
||||
"mesh-build-machine.built",
|
||||
// The build seat node-build-agent and the retired mesh-build-machine went with build-agent (novox/hq ADR 0524 §5,
|
||||
// ADR 0525 §10): no build seat says `built` since R4g, so what the mesh holds is asked when this module starts.
|
||||
// What the mesh already held, when this module asks what it missed (novox/hq ADR 0134).
|
||||
"mesh-controller.built-before",
|
||||
] as const;
|
||||
|
||||
@@ -26,8 +26,6 @@
|
||||
"postgres-database": "${dir:state}/database.secret"
|
||||
},
|
||||
"consumes": [
|
||||
"node-build-agent.built",
|
||||
"mesh-build-machine.built",
|
||||
"mesh-controller.built-before"
|
||||
],
|
||||
"emits": [
|
||||
|
||||
@@ -20,8 +20,10 @@ const walkBuild = {
|
||||
made: [{ name: "code", kind: "bundle", reference: "artifact-store://mailu/code/blobs/sha256:d041" }],
|
||||
};
|
||||
|
||||
test("the catalogue hears the build seat that builds now, not only the retired one (issue 712)", async () => {
|
||||
assert.ok(BUILD_EVENTS.includes("node-build-agent.built"));
|
||||
test("the catalogue hears no retired build seat, and what the mesh held (issue 712, issue 1887 E2)", async () => {
|
||||
for (const retired of ["node-build-agent.built", "mesh-build-machine.built"]) {
|
||||
assert.ok(!(BUILD_EVENTS as readonly string[]).includes(retired), `${retired} is still heard`);
|
||||
}
|
||||
assert.ok(BUILD_EVENTS.includes("mesh-controller.built-before"));
|
||||
// Subscribing is not enough: the mesh grants and routes only what the manifest consumes.
|
||||
const manifest = JSON.parse(await readFile(new URL("../module.json", import.meta.url), "utf8"));
|
||||
|
||||
@@ -96,9 +96,9 @@ func TestAConsumerWithSeveralFiltersIsHandedEveryMessage(t *testing.T) {
|
||||
FilterSubjects: []string{
|
||||
"mesh.mod.mesh-catalog.event.upgraded",
|
||||
"mesh.mod.mesh-catalog.event.catching-up",
|
||||
"mesh.seat.node-build-agent.event.built",
|
||||
"mesh.seat.node-backup.event.done",
|
||||
"mesh.mod.gitea.event.pull.merged",
|
||||
"mesh.seat.mesh-build-machine.event.built",
|
||||
"mesh.seat.node-power.event.slept",
|
||||
"mesh.mod.*.event.provisioner.failing",
|
||||
"mesh.mod.*.event.provisioner.recovered",
|
||||
},
|
||||
@@ -128,7 +128,7 @@ func TestAConsumerWithSeveralFiltersIsHandedEveryMessage(t *testing.T) {
|
||||
}
|
||||
}()
|
||||
|
||||
followed := []string{"mesh.mod.gitea.event.pull.merged", "mesh.seat.node-build-agent.event.built",
|
||||
followed := []string{"mesh.mod.gitea.event.pull.merged", "mesh.seat.node-backup.event.done",
|
||||
"mesh.mod.postgres.event.provisioner.recovered", "mesh.mod.mesh-catalog.event.catching-up"}
|
||||
var mu sync.Mutex
|
||||
var sent []uint64
|
||||
@@ -153,7 +153,7 @@ func TestAConsumerWithSeveralFiltersIsHandedEveryMessage(t *testing.T) {
|
||||
mu.Unlock()
|
||||
}
|
||||
} else {
|
||||
_, _ = pjs.Publish(fmt.Sprintf("mesh.seat.node-build-agent.event.log.build-%d-%d", w, i/50), make([]byte, 200))
|
||||
_, _ = pjs.Publish(fmt.Sprintf("mesh.seat.node-backup.event.log.run-%d-%d", w, i/50), make([]byte, 200))
|
||||
}
|
||||
if rand.Intn(100) == 0 {
|
||||
time.Sleep(time.Duration(rand.Intn(300)) * time.Millisecond)
|
||||
|
||||
Reference in New Issue
Block a user