mesh/delivery merged: source.main moved to novox/mesh-delivery@bcb5aafdbe80
mesh/check pass 3e8bd9b0def2 on bcb5aafdbe80 | unit 168 run, 472 kept | integration 178 run, 538 kept | composition passed on shanks
mesh-delivery #51's re-ask never fired for mesh-build-node.4e7b118e: messages the SEAT_NODE_BUILD_GO workers had given up on stay on the work queue, and each counted as waiting ahead, so the ask was never asked again (note 62). A message ahead now waits only when no node wrote its step and no ask of its kind asked after it was taken; the old message of an ask asked again is deleted from its stream; and builder_seat_queue (answered by the builder through its queues state, as only its account may read the stream) shows each message and whether it still waits.
50 lines
1.6 KiB
Go
50 lines
1.6 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"time"
|
|
|
|
"github.com/nats-io/nats.go/jetstream"
|
|
|
|
"mesh-delivery-builder/internal/build"
|
|
)
|
|
|
|
// queueReader is the part of the builder a queues value reads through: heldOnTheBus.
|
|
type queueReader interface {
|
|
Queue(ctx context.Context, language string, limit int) (build.SeatQueue, error)
|
|
}
|
|
|
|
// queueRead answers one value of the queues state (the tool builder_seat_queue, issue 1945 note 62): a value not yet
|
|
// answered is read now, from the stream the builder's account may read, and written back by compare-and-set at its
|
|
// revision with what was read or why it could not be. A value answered already (this builder's own write, or another
|
|
// instance's) or deleted is left.
|
|
func queueRead(ctx context.Context, r queueReader, kv jetstream.KeyValue, e jetstream.KeyValueEntry, logf func(string, ...any)) {
|
|
if e.Operation() != jetstream.KeyValuePut {
|
|
return
|
|
}
|
|
a, err := build.DecodeQueueAsk(e.Value())
|
|
if err != nil {
|
|
logf("%s.%s holds what is not a queue read, left: %v", build.QueuesState, e.Key(), err)
|
|
return
|
|
}
|
|
if !a.Answered.IsZero() {
|
|
return
|
|
}
|
|
read, cancel := context.WithTimeout(ctx, 20*time.Second)
|
|
q, err := r.Queue(read, e.Key(), max(1, min(a.Limit, build.MaxQueueLimit)))
|
|
cancel()
|
|
if err != nil {
|
|
a.Error = err.Error()
|
|
}
|
|
a.Queue, a.Answered = &q, time.Now().UTC()
|
|
data, err := json.Marshal(a)
|
|
if err != nil {
|
|
return
|
|
}
|
|
if _, err := kv.Update(ctx, e.Key(), data, e.Revision()); err != nil && !errors.Is(err, jetstream.ErrKeyExists) && !errors.Is(err, jetstream.ErrKeyRevisionMismatch) {
|
|
logf("%s.%s: the read could not be written: %v", build.QueuesState, e.Key(), err)
|
|
}
|
|
}
|