Builder: a by-hand build answers an ask as asked once it is put, not once noted
builder_build_again's answer (BuildAgainResult.Asks: "the ask ids put") was settled when the ask's id was noted in the key, before its put: the answer could come back naming an ask not yet on its stream (the check's flake in TestAnAskTheKeyNamesAndNobodyPutIsPutAtStart, "after 0 asks", about 4 runs in 100 under load), and a put the stream refused after the note was answered as asked, the key's failure unsaid. The watch is now told after the put; a refused put ends the look and the answer says the key's failure. Builds: lead answer A-148 (hq G-20, 3ce1dcf: the fix rides the release), issue 1126 note 72 (builder_build_again answers the asks put), ADR 0668 §1 (the note and the put are one act) Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user