A build says what it does on the bus, as it happens (novox/hq ADR 0157)
The build-machine seat emits `started` and `log.<build id>` beside `built`. Every line the builder speaks — each step, each command with its duration, and on failure the command's own output — goes to stderr as before and onto the bus under the build's id, one subject per build, kept a week in EVENTS with every other event. `builds --log <id>` reads it back from the stream with a consumer that is gone when the reading is done, on the command line and as the controller's seat verb; `builds` lists each build's id and `build` says the id it asked with. Lines are core publishes with a sequence number, so a build is not slowed by an ack per line and a gap is visible; `started` and `built` are awaited into the stream. The seat protocol widens additively at the controller's next start; the holder's grant follows on the broker node's next composition.
This commit is contained in:
@@ -79,6 +79,14 @@ func TestNatsABuildIsTakenAndItsOutcomeReachesEverybody(t *testing.T) {
|
||||
defer func() { _ = watching.Unsubscribe() }()
|
||||
_ = js.Conn().Flush()
|
||||
|
||||
// And a reader following this one build by its subject alone (novox/hq ADR 0157).
|
||||
lines, err := js.Conn().SubscribeSync(BuildLog("b-1"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer func() { _ = lines.Unsubscribe() }()
|
||||
_ = js.Conn().Flush()
|
||||
|
||||
// A build machine holding the role.
|
||||
machine := MachineOverNATS(js, "anchor")
|
||||
defer machine.Close()
|
||||
@@ -86,6 +94,9 @@ func TestNatsABuildIsTakenAndItsOutcomeReachesEverybody(t *testing.T) {
|
||||
go func() {
|
||||
failed <- machine.Take(ctx, func(ctx context.Context, work Build) {
|
||||
r := work.Request()
|
||||
_ = work.Began(ctx)
|
||||
work.Say("clone", "cloning /r")
|
||||
work.Say("image", "building shop")
|
||||
_ = work.Announce(ctx, BuildResult{
|
||||
ID: r.ID, Repository: r.Repository, On: "anchor", Commit: "abc1234",
|
||||
Manifest: json.RawMessage(`{"module":"shop"}`),
|
||||
@@ -104,6 +115,27 @@ func TestNatsABuildIsTakenAndItsOutcomeReachesEverybody(t *testing.T) {
|
||||
}
|
||||
t.Fatalf("the asker never got an outcome: %v", err)
|
||||
}
|
||||
// The reader heard the build as it went, in order, under its id.
|
||||
for want := 1; want <= 2; want++ {
|
||||
msg, err := lines.NextMsg(5 * time.Second)
|
||||
if err != nil {
|
||||
t.Fatalf("line %d of the build never reached its subject: %v", want, err)
|
||||
}
|
||||
var line BuildLine
|
||||
if err := json.Unmarshal(msg.Data, &line); err != nil || line.ID != "b-1" || line.Seq != want {
|
||||
t.Fatalf("line %d came back as %s (%v)", want, msg.Data, err)
|
||||
}
|
||||
}
|
||||
// And it is in the stream for a reader who comes later.
|
||||
info, err := js.Context().StreamInfo(broker.EventsStream, &nats.StreamInfoRequest{SubjectsFilter: BuildLog("b-1")})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if info.State.Subjects[BuildLog("b-1")] != 2 {
|
||||
t.Fatalf("the stream holds %v under the build's subject, want 2", info.State.Subjects)
|
||||
}
|
||||
if err == nil {
|
||||
}
|
||||
if result.ID != "b-1" || result.Commit != "abc1234" {
|
||||
t.Fatalf("the asker got %+v", result)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user