webSocketMessage() blocks subsequent messages on the same connection
dannyhagenlocker opened 路
Celld v0.6.0 waits for an asynchronous `webSocketMessage()` handler to finish before dispatching the next message on the same connection. This prevents Cloudflare's `AIChatAgent` from processing cancellation while its message handler is awaiting a streaming response, leaving `options.abortSignal` untriggered until the turn has already finished.
The behavior can be demonstrated without an AI provider. On a socket accepted with `ctx.acceptWebSocket()`, use this handler:
```js async webSocketMessage(ws, message) { if (message === "start") { ws.send("started"); await new Promise(resolve => setTimeout(resolve, 2000)); ws.send("finished"); } else { ws.send("cancel-received"); } } ```
Send `start`, then send `cancel` on the same connection 100 ms after receiving `started`. To match Workerd, expected behavior is for `cancel-received` to arrive before `finished`. On celld, it arrives only after the two-second handler completes. Sending cancellation through a second connection to the same object also works on celld.
The [socket read loop](https://github.com/denoland/celld/blob/bad4649d01f0db84cdc9093527e72e64ca7a14bf/crates/celld/main/websocket.rs#L664-L691) awaits each dispatch before reading the next frame. #229 fixed outgoing streaming, but incoming messages still wait for handler completion.
Could celld dispatch incoming messages in arrival order while allowing asynchronous handlers to overlap, preserving its existing concurrency and durability gates and tracking each handler through completion, failure, and shutdown?
- BA
Thanks for the report. This is now fixed and will be shipped in v0.6.1
bartlomiejureferenced 9ff48569e312last month on GitHub
bartlomiejureferenced f2bf648663a6last month on GitHub
ewhauserreferenced this in Merge upstream celld v0.6.1 #90last month on GitHub
futurepaulreferenced this in runtime: a cell event settled in another event's turn is answered at once #3last month on GitHub