0.1.13: one rule for taking an event, and no handler left by a refused subscribe (hq issue 276) #10

Merged
mesh-admin merged 1 commits from fix/an-event-handler-answers-what-it-did into main 2026-10-06 16:17:06 +00:00
Contributor

The rule, written down in README "Taking an event", the on() doc and stdio.Subscribe's doc: a handler takes an event by returning and asks for it again by throwing (in Go, returning an error). On the wire, any mesh/event answer that is not a JSON-RPC error takes the event. An error, no answer within the event timeout, or the bundle exiting gets it offered again after 5s, up to max-deliveries, after which the controller raises max-deliveries. So a handler throws only when the work was not done, and its work must be safe to repeat, or it skips an event.id it already handled. This came out of plex on ace, which threw after a successful rescan because it parsed an empty 200 body.

Fix, found on the way: both SDKs added the handler before mesh/subscribe was answered and kept it when the runtime refused. A module that keeps asking until the runtime takes it (every Go consumer does this) then ran the same handler once per attempt for every event. Now:

  • TS removes the handler when the subscribe is refused.
  • Go removes it when the runtime answered with an error. If the runtime did not answer in time, Go keeps the handler, because the runtime may have bound it.

Tests: a new TS stdio test with fixture stdio-resubscribe.mjs, and Go TestARefusedSubscribeLeavesNoHandlerBehind. Both fail without the fix and pass with it. All TS stdio tests pass, and go test ./... passes.

Rollout: the package version goes to 0.1.13, and the pipeline publishes it. Go consumers (postgres, records, messenger, mesh-watcher) pick up the fix only after a go/v0.1.13 tag and a bump of their SDK version. I did not create the tag.

Related: novox/mesh-media-catalog#5, novox/mesh-tools, novox/hq issue 276.

**The rule, written down in README "Taking an event", the `on()` doc and `stdio.Subscribe`'s doc:** a handler takes an event by returning and asks for it again by throwing (in Go, returning an error). On the wire, any `mesh/event` answer that is not a JSON-RPC error takes the event. An error, no answer within the event timeout, or the bundle exiting gets it offered again after 5s, up to max-deliveries, after which the controller raises `max-deliveries`. So a handler throws only when the work was not done, and its work must be safe to repeat, or it skips an `event.id` it already handled. This came out of plex on ace, which threw after a successful rescan because it parsed an empty 200 body. **Fix, found on the way:** both SDKs added the handler before `mesh/subscribe` was answered and kept it when the runtime refused. A module that keeps asking until the runtime takes it (every Go consumer does this) then ran the same handler once per attempt for every event. Now: - TS removes the handler when the subscribe is refused. - Go removes it when the runtime answered with an error. If the runtime did not answer in time, Go keeps the handler, because the runtime may have bound it. **Tests:** a new TS stdio test with fixture `stdio-resubscribe.mjs`, and Go `TestARefusedSubscribeLeavesNoHandlerBehind`. Both fail without the fix and pass with it. All TS stdio tests pass, and `go test ./...` passes. **Rollout:** the package version goes to 0.1.13, and the pipeline publishes it. Go consumers (postgres, records, messenger, mesh-watcher) pick up the fix only after a `go/v0.1.13` tag and a bump of their SDK version. I did not create the tag. Related: novox/mesh-media-catalog#5, novox/mesh-tools, novox/hq issue 276.
mesh-admin added 1 commit 2026-10-06 16:16:31 +00:00
A handler takes an event by returning and asks for it again by throwing;
any mesh/event answer but an error is taken. Written down in the README
where event handling is, with what follows for a handler: throw only when
the work was not done, and be safe to run twice.

Both SDKs added the handler before asking the runtime and kept it when the
runtime refused, so a module that asks again until it is taken (every Go
consumer does) ran its handler once per attempt for every event. A refused
subscribe now removes its handler; one the Go runtime did not answer in
time is kept, since the runtime may have bound it.
mesh-admin merged commit 89da342b9a into main 2026-10-06 16:17:06 +00:00
mesh-admin deleted branch fix/an-event-handler-answers-what-it-did 2026-10-06 16:17:06 +00:00
Author
Contributor

Delivery novox/mesh-sdk@9f875b3d5c2f — delivered since 2026-10-06T23:05:28Z

Transitions

  • 2026-10-06 23:05 (new) → proposed (announced): novox/mesh-sdk#10 merged; its head was not heard by this owner, so it is made from the forge's word
  • 2026-10-06 23:05 proposed → held (merged-unchecked): merged without a passing check — a verdict known with it is taken first: only a person decides that it goes on
  • 2026-10-06 23:05 held → delivering (go): its walk started on a word that was not this owner's: the controller's own path, which waits for nobody, or a person's plans go
  • 2026-10-06 23:05 delivering → delivered (done): its walk is done: every machine of its deploy plan passed, or was left as its policy says

The commit's note under refs/notes/mesh-plan keeps every transition: git log --notes=mesh-plan.

<!-- mesh-delivery:view --> **Delivery** `novox/mesh-sdk@9f875b3d5c2f` — **delivered** since 2026-10-06T23:05:28Z **Transitions** - 2026-10-06 23:05 (new) → proposed (announced): novox/mesh-sdk#10 merged; its head was not heard by this owner, so it is made from the forge's word - 2026-10-06 23:05 proposed → held (merged-unchecked): merged without a passing check — a verdict known with it is taken first: only a person decides that it goes on - 2026-10-06 23:05 held → delivering (go): its walk started on a word that was not this owner's: the controller's own path, which waits for nobody, or a person's `plans go` - 2026-10-06 23:05 delivering → delivered (done): its walk is done: every machine of its deploy plan passed, or was left as its policy says The commit's note under `refs/notes/mesh-plan` keeps every transition: `git log --notes=mesh-plan`.
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-sdk#10