v0.10.7
sigil-websocket v0.10.7
ws-receive-nowait can now make progress on its own
v0.10.6 fixed ws-receive-nowait so that it exists at all, but shipped it buffer-only: it returned what was already decodable in the connection buffer and never read the socket. That is not enough to drive a receive loop, and the gap is worth stating as the measurement rather than the argument.
Against 0.10.6, a holder pump using ws-receive-nowait exclusively traces take-message! -> #f connected?=y repeating forever: the pump turns, the holder is alive, and nothing ever arrives. Buffer-only cannot make progress because nothing fills the connection buffer unless something reads the socket. The identical harness opens ZERO sessions on 0.10.6 and 3/3 on this release.
What changed
ws-receive-nowait now drains the buffer first, then takes exactly one socket read when it can do so without waiting.
The buffer comes first deliberately. One socket read routinely yields several complete frames, and draining what is already decodable is what stops the second and third frames being stranded behind a quiet socket.
The socket read happens only when a scheduler is present. ws-connect sets the socket non-blocking precisely (when (current-scheduler)), so that same condition is the honest test for whether a read can be taken without blocking, rather than a flag that cannot be queried uniformly across TCP and TLS. Outside a scheduler the procedure degrades to buffer-only, which is the strongest thing that can be promised there.
A would-block read returns need-more, which becomes #f. A partial frame is still not an error.
Verification
Gated through a real consumer rather than in isolation, because the defect this area hid behind was invisible to unit tests: slate-cli built against this branch, driving a real slate node _stream holder over a relay, answered 2/2 and 3/3 session-open requests with real pty output returned and the holder alive throughout.
Upgrading
^0.10 resolves this. If you are on 0.10.6 and your receive loop never receives anything, this is why.
6c181e52c71a2838980fc376e1e062176ee9dd45
This commit is older than the 20 that keep a page here, so it has none. It is in the clone.