diff --git a/modules/mesh-delivery-builder/internal/build/run.go b/modules/mesh-delivery-builder/internal/build/run.go index a7711f09..bd3299b7 100644 --- a/modules/mesh-delivery-builder/internal/build/run.go +++ b/modules/mesh-delivery-builder/internal/build/run.go @@ -870,11 +870,7 @@ func (n *askNotes) note(ctx context.Context, language, id, step string) error { v.Asks = map[string]string{} } v.Asks[language] = id - if err := n.b.Claimer.Finish(ctx, n.cl, v); err != nil { - return err - } - n.b.handAsk(n.cl.Key, language, id) - return nil + return n.b.Claimer.Finish(ctx, n.cl, v) } // runLane puts the lane's part of the build as one ask on its build seat's stream (the delivery stream for a trunk key, the @@ -959,6 +955,9 @@ func (b *Builder) runLane(ctx context.Context, l *lane, repository string, m mes l.err = err return } + // A request to build the key again by hand is answered the ask as asked once it is put, not once it is noted: a + // put the stream refuses after the note answers the key's failure (BuildAgainResult.Asks). + b.handAsk(asked.cl.Key, language, ask.ID) } step, ask, err := b.answer(ctx, l, ask, asked, module, m.Fp2) if err != nil { diff --git a/modules/mesh-delivery-builder/internal/build/run_test.go b/modules/mesh-delivery-builder/internal/build/run_test.go index cfc3ad9b..b6e5d150 100644 --- a/modules/mesh-delivery-builder/internal/build/run_test.go +++ b/modules/mesh-delivery-builder/internal/build/run_test.go @@ -983,6 +983,8 @@ func TestABuildAskWaitingInItsStreamIsNotBounded(t *testing.T) { during bool // standing is a key taken as it stands (left building): its claim is the key's own revision, not a new one. standing bool + // putRefused is a stream that refuses the ask after its note was written to the key. + putRefused bool }{ {name: "build again: a look the builder queued during the by-hand build still runs afterwards", again: true, during: true, key: &builds.BuilderBuild{State: builds.BuildFailed, Error: "ace: no tun"}}, @@ -1000,6 +1002,10 @@ func TestABuildAskWaitingInItsStreamIsNotBounded(t *testing.T) { {name: "build again: a build that fails before its asks says the key failed, not that it was asked", again: true, failed: "cannot be read", edit: func(m *meshcatalog.ModulesByModuleValue) { m.Manifest = mdigest('b') }, key: &builds.BuilderBuild{State: builds.BuildFailed, Error: "ace: no tun"}}, + // An ask is answered as asked only once it is put, not once it is noted in the key (BuildAgainResult.Asks): a put + // the stream refuses after the note answers the key's failure and no ask id. + {name: "build again: an ask its stream refuses after its note answers the key failed, not asked", again: true, putRefused: true, + failed: "the stream refused the ask", key: &builds.BuilderBuild{State: builds.BuildFailed, Error: "ace: no tun"}}, {name: "build again: a failed key is written building as a new revision and asks the seat", again: true, key: &builds.BuilderBuild{State: builds.BuildFailed, Error: "ace: the step failed: no tun"}}, {name: "build again: a done key is refused, nothing to do", again: true, refuse: "is done: nothing to do", @@ -1057,6 +1063,9 @@ func TestABuildAskWaitingInItsStreamIsNotBounded(t *testing.T) { r.b.hands[r.key] = &handWatch{} } r.b.known["m"] = m // the builder has read the modules value, and looks at nothing until asked + if c.putRefused { + r.b.Asks = buildrun.Asker{Publisher: refusingPublisher{}, Waiter: r.asks, Bound: 2 * time.Second} + } if c.standing { r.b.tried[r.key] = true // its look of the key ended before its write: a later look takes over nothing by itself } @@ -1330,6 +1339,13 @@ func TestABuildAskWaitingInItsStreamIsNotBounded(t *testing.T) { }) } +// refusingPublisher is an asks stream that refuses every ask. +type refusingPublisher struct{} + +func (refusingPublisher) PublishAsk(context.Context, string, string, []byte) error { + return errors.New("the stream refused the ask") +} + // heldAsks says an ask is held when its id is among held. type heldAsks map[string]bool