A consumer a machine is bound to keeps the subject that works #148

Merged
jschoubben merged 1 commits from fix/156-a-consumer-that-works-is-not-replaced into main 2026-09-29 21:56:53 +00:00
Owner

Fixes novox/hq issue 156. The control plane is crash-looping on the live mesh right now; this is what stops it.

Issue 146 put the stream into a push consumer's delivery subject. The server will not move that subject while a subscriber is bound, and answers consumer name already in use. A node is bound to its declaration consumer the whole time it is up, so every node consumer in a running mesh became one the assertion could not bring to match — and the assertion runs before the controller serves.

Kept rather than re-made: the live nodes are granted _DELIVER.<node> and not _DELIVER.<node>.>, so re-making would have silenced every machine. Kept rather than fatal, which is what 146's change intended.

Two tests against a real server. Reproduced the exact production error before fixing.

Fixes novox/hq issue 156. **The control plane is crash-looping on the live mesh right now**; this is what stops it. Issue 146 put the stream into a push consumer's delivery subject. The server will not move that subject while a subscriber is bound, and answers `consumer name already in use`. A node is bound to its declaration consumer the whole time it is up, so every node consumer in a running mesh became one the assertion could not bring to match — and the assertion runs before the controller serves. Kept rather than re-made: the live nodes are granted `_DELIVER.<node>` and not `_DELIVER.<node>.>`, so re-making would have silenced every machine. Kept rather than fatal, which is what 146's change intended. Two tests against a real server. Reproduced the exact production error before fixing.
jschoubben added 1 commit 2026-09-29 21:56:46 +00:00
novox/hq 04-ISSUES/156. Issue 146 put the stream into a push consumer's
delivery subject. The server will not move that subject while a
subscriber is bound, and answers `consumer name already in use` — a
message about the name, for a conflict about the subject. A node is bound
to its declaration consumer the whole time it is up: that IS a node
listening. So every node consumer in a running mesh became one the
assertion could not bring to match, and the control plane crash-looped on
the assertion it makes before it serves. A fresh mesh showed nothing,
because nothing was bound.

Kept rather than deleted and re-made. Re-making moves the subject, and a
holder may not be allowed to subscribe to the new one yet: the wider
grant travels in the bus's user list, which this same control plane
composes and a machine applies minutes later. On the live mesh the nodes
are granted `_DELIVER.<node>` and not `_DELIVER.<node>.>`, so re-making
would have silenced every machine — worse than the collision it fixes,
and harder to undo.

Kept rather than fatal, which is what 146's change intended and did not
do. The bare subject still delivers, and collides only where one holder
has two consumers of one name. That is the controller's own pair, and the
controller is not bound to them while it asserts, so those do move.

Also: an existing consumer's deliver policy is carried across rather than
reasserted, because the server refuses to change it and where a consumer
starts is its history.

Two tests against a real server: a consumer with a subscriber bound keeps
its subject, is reported, and still delivers; one with nothing bound
moves, so 146's fix still applies where it matters.
jschoubben merged commit e7da39de57 into main 2026-09-29 21:56:53 +00:00
jschoubben deleted branch fix/156-a-consumer-that-works-is-not-replaced 2026-09-29 21:56:53 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: novox/mesh-controller#148