Skip to content

fix(websocket): preserve JOIN ordering during target handoff - #964

Merged
wolfy-j merged 1 commit into
mainfrom
fix/wsrelay-handoff-order-20261012
Oct 12, 2026
Merged

wolfy-j merged 1 commit into
mainfrom
fix/wsrelay-handoff-order-20261012

Conversation

@wolfy-j

@wolfy-j wolfy-j commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

Defect

The websocket read goroutine can send a command to the newly published target before its JOIN notification. An in-flight old-target send can also finish after LEAVE. Connected-client ownership enforcement in wippyai/framework#176 correctly rejects both out-of-order commands.

Fix

Serialize command enqueueing and handoff notifications with a private connection mutex. Complete topology preparation outside that mutex, enqueue LEAVE/JOIN in per-sender FIFO, and publish the new target and optional message topic only after JOIN is accepted. State-only controls remain independent of relay backpressure.

Canceled handoffs release the newly acquired monitor. Failed JOIN closes the connection instead of retaining an unjoined target; failed LEAVE still permits a reachable replacement. Failed sends release sender-owned relay packages.

Compatibility

Existing target, message-topic, metadata and heartbeat configuration fields retain their meaning. Client PIDs, wire payloads and normal connected-client routing are preserved. This changes failed-JOIN handling from a silent broken connection to closure. The serializer is internal; it adds no process option or host configuration.

Verification

  • Five regressions fail on unmodified runtime main; the fixed handoff tests pass.
  • Eleven added cases cover JOIN ordering, in-flight sends, topic/metadata publication, unchanged/invalid targets, monitor and JOIN failures, cancellation, failed LEAVE, metadata-only controls under backpressure, and omitted optional fields.
  • Complete wsrelay package passes under the race detector, including five repeated runs. Go vet and configured golangci-lint pass.
  • Local runtime build passes all 36 Framework relay cases, including the real registry-driven user-hub live update: same PID, actor, plugin and client ownership, 32 queued commands, and existing upgradable/trap_links options.
  • Original relay dependency lock retained. Command-send benchmark remains 88 bytes / 4 allocations per operation. Host load makes timing comparisons inconclusive.

Deploy the fixed runtime before rolling out the strict relay ownership guard in framework#176.

@wolfy-j
wolfy-j merged commit 43aa8f6 into main Oct 12, 2026
21 checks passed
@wolfy-j
wolfy-j deleted the fix/wsrelay-handoff-order-20261012 branch October 12, 2026 19:38
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.

2 participants