mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-10-06 03:38:23 +00:00
Nip42AuthDmDeliveryTest stalled for its full 10s timeout on CI while passing locally. The stall is a race in InProcessWebSocket.connect(): server.connect() runs the session's connect-time policies synchronously, so FullAuthPolicy's AUTH challenge reached the client's listener before the socket assigned its `incoming` channel and before onOpen fired — breaking the WebSocketListener contract (no onMessage before onOpen). RelayAuthenticator answers that challenge on its own coroutine. When the signed AUTH reply hit send() before the connect thread reached the `incoming` assignment, send() returned false and the reply was silently dropped. Nothing recovers from that: the challenge is already dedup'd as answered, and an EVENT rejected with OK-false `auth-required:` never re-triggers auth (only a CLOSED does), so the pending gift wrap was never resent — exactly the CI signature (10.011s, no auth activity between the authenticator's Init and Destroy logs). Server->client frames now go through an outbound channel drained by a coroutine started only after onOpen, so every connect-time frame reaches the listener with the socket fully wired. Order is preserved by the single drainer, same as the existing inbound path. Both new InProcessWebSocketTest cases fail deterministically without the reorder (the challenge always outran onOpen; a reply sent from the first onMessage was always rejected) and pass with it, on top of the full :geode:test and :quartz:jvmTest suites. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bf1Y91sfjxwi2ig4ymGTA9