Skip to content

fix: stable, caller-supplied broker session id (survives reconnect)#40

Open
iRonin wants to merge 1 commit into
nicobailon:mainfrom
iRonin:fix/stable-session-derived-id
Open

fix: stable, caller-supplied broker session id (survives reconnect)#40
iRonin wants to merge 1 commit into
nicobailon:mainfrom
iRonin:fix/stable-session-derived-id

Conversation

@iRonin

@iRonin iRonin commented Jun 11, 2026

Copy link
Copy Markdown

Summary

Makes the broker routing identity stable across reconnects by letting the client supply its own id (the pi session id) at register time. Relates to #39; complementary to #35/#37.

Problem

broker.ts assigns const id = randomUUID() on every register, so the routing identity changes on every reconnect. A peer that resolved a name → id (the normal send/ask path does resolveSessionTargetclient.send(<id>)) hits delivery_failed: "Session not found" the moment the target reconnects with a new id — even though the target is alive and correctly named. Sending "by name" is affected too, because the sender resolves the name to an id first and then routes by id.

Fix

  • register accepts an optional caller-supplied sessionId. When present the broker uses it as the routing identity; otherwise it falls back to randomUUID() (older clients unaffected).
  • The extension passes the pi session id as that stable id. Reconnects keep the same id, so a previously-resolved id stays valid.
  • Harden the socket-close handler: only evict a registry entry when it still points at the closing socket, so a reconnect that rebinds the id before the old socket's close fires isn't torn down by that late close.

Side benefit: the list/parens id, any status surface, and the subagent-chat-* fallback alias converge on one stable id instead of three different values.

Compatibility

Protocol-additive (sessionId? on register). A mixed fleet works: clients that don't send it still get a random id. No behavior change for clients that never reconnect.

Test

A worker connects with a stable id; a peer resolves it; the worker reconnects (new socket, same id); the peer's send to the same id still delivers. Verified the test fails with per-connect random ids and passes with the fix. Full suite 37/37.

…tity

The broker assigned a fresh randomUUID() on every register, so the routing
identity changed on every reconnect. A peer that resolved a name to an id (or
sent by id) would hit "Session not found" once the target reconnected with a
new id \u2014 even though the target was alive and named.

Let the client supply a stable id (the pi session id) in the register message;
the broker uses it as the routing identity when present and falls back to
randomUUID for older clients. Reconnects keep the same id, so previously
resolved ids stay valid. As a side effect the list/parens id, any status
surface, and the subagent-chat-* fallback alias all converge on one stable id.

Also harden the socket-close handler: only evict a registry entry if it still
points at the closing socket, so a reconnect that rebinds the id before the old
socket's close fires is not torn down by that late close.

Test: a worker connects with a stable id, a peer resolves it, the worker
reconnects (new socket, same id), and the peer's send to the SAME id still
delivers. Verified the test fails with per-connect random ids.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant