Join a paged answer, and say one too large instead of timing out (hq issue 314)
mesh/merge-gate pass: builds mesh-tools, node-tools → ace, g14, novox, shanks; no bus step; every machine composes with the change as it did without (4 of …
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery delivered
mesh/delivery-group group fix/314-a-large-answer-is-paged-not-lost delivered: every member is delivered

An answer larger than the bus's max_payload was refused by the client library
inside its holder, and the caller waited out its 30 s and read silence: the
controller's conditions and status for hours on 2026-10-08. The console now asks
for the parts of an answer the controller paged and joins them; a module's answer
too large for one message is answered as an error saying so, at once.
This commit is contained in:
jochen
2026-10-08 11:25:50 +02:00
parent 9a4140b49b
commit 90c7871276
3 changed files with 214 additions and 2 deletions
+11 -2
View File
@@ -449,7 +449,11 @@ func (c *Conn) answerOn(subject, queue string, h Handler) (func(), error) {
}
r.Node = c.node
body, _ := wire.Marshal(r)
_ = msg.Respond(body)
// Within what the bus carries, or said to be too large — never a send the library
// refuses and the caller waits out (novox/hq issue 314).
if err := msg.Respond(c.fits(subject, body)); err != nil {
c.Logf("[mesh-tools] could not answer on %s: %v", subject, err)
}
}()
}
var sub *nats.Subscription
@@ -614,13 +618,18 @@ func (c *Conn) askOnce(subject string, data []byte) (Answered, bool, error) {
}
return Answered{}, false, err
}
// An answer larger than one message comes in parts (pages.go, novox/hq issue 314).
body, err := c.whole(subject, msg.Data)
if err != nil {
return Answered{}, false, err
}
var r struct {
Result json.RawMessage `json:"result"`
Error string `json:"error"`
Node string `json:"node"`
Retry string `json:"retry"`
}
if err := json.Unmarshal(msg.Data, &r); err != nil {
if err := json.Unmarshal(body, &r); err != nil {
return Answered{}, false, err
}
if r.Error != "" {