feat: add std/ws WebSocket module and std/io terminal size detection to allow multiplayer snake#377
Draft
notactuallytreyanastasio wants to merge 12 commits intodo-crimes-to-play-snakefrom
Conversation
Contributor
|
We had a decorator called |
Contributor
Author
|
@ShawSumma I could see that being pretty valuable from a DX perspective. |
Contributor
|
Our earlier issue for this was #130, it wasn't super developed, but there was thought into this for Filesystems specifically |
e25c48b to
085161f
Compare
JsRunFileLayoutTest: add io.js and keyboard.js to expected file trees in both std/ and temper-core/ directories. ReplTest: allow scheduler call in Lua translation output. Signed-off-by: Robert Grayson <bobbbygrayson+github@gmail.com> Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Robert Grayson <bobbbygrayson+github@gmail.com>
…nner The Rust backend uses a SingleThreadAsyncRunner, so the blocking crossterm::event::read() call was starving the game tick coroutine. Spawn a real OS thread for the blocking read and complete the promise from there, allowing other async tasks to proceed concurrently. Signed-off-by: Robert Grayson <bobbbygrayson+github@gmail.com> Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Robert Grayson <bobbbygrayson+github@gmail.com>
Rebased onto do-crimes-to-play-snake: resolved conflicts with std/keyboard, updated Rust terminal size to use crossterm instead of libc, added ws to stdSupportNeeders set.
The ws.js support file dynamically imports the 'ws' package, but it wasn't listed as a dependency. After temper build regenerated the output, npm install wouldn't install ws, causing wsListen/wsConnect to fail silently at runtime. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Rename support functions to std_ws_* to avoid colliding with Temper-generated panic stubs (same pattern as std_sleep/std_read_line) - Change visibility from pub(crate) to pub for cross-crate access - Accept &dyn WsServerTrait/WsConnectionTrait instead of &WsServer to work with the Rust backend's interface deref codegen - Use WsStream enum to handle both WebSocket<TcpStream> (server-accepted) and WebSocket<MaybeTlsStream<TcpStream>> (client-connected) - Use temper_core::cast() for downcasting instead of manual as_any chain - Add .into() for tungstenite 0.26 Message::Text(Utf8Bytes) change Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Temper's Rust runtime uses a single-threaded task runner. Blocking ws operations (accept, send, recv) would block the runner and prevent other async blocks (like readLine) from processing. Spawn dedicated threads for ws_accept, ws_send, and ws_recv instead of going through crate::run_async. This lets the WS operations block independently while other async work continues. Also adds error logging to ws_recv for debugging. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Both server-accepted and client connections now have a 50ms read timeout. This prevents the recv loop from holding the socket Mutex indefinitely, allowing send operations to interleave. Without this, the Rust server couldn't send frames because recv blocked the lock. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace Mutex-shared WebSocket with a dedicated I/O thread per connection that communicates via mpsc channels. The I/O thread owns the WebSocket exclusively and polls for both send and recv, avoiding tungstenite's internal state corruption from concurrent access. Send is now non-blocking (channel push), recv blocks on the channel receiver in a spawned thread. This fixes the ResetWithoutClosingHandshake error that occurred when the server's recv loop and send loop competed for the socket. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
tungstenite corrupts internal state when read/write are interleaved from different threads, even with Mutex protection. Replace it with a minimal WebSocket implementation (~150 lines) that: - Does HTTP upgrade handshake byte-by-byte (avoids BufReader read-ahead) - Uses TcpStream::try_clone() to split into independent read/write halves - Reader thread owns the read half, writer Mutex holds the write half - No shared internal framing state — reads and writes are independent - SHA-1 for the accept key via sha1_smol (only external dep) Also removes the sleep() debug logging. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Wire WebSocket support (wsListen, wsAccept, wsConnect, wsSend, wsRecv, wsClose) and terminal size detection (terminalColumns, terminalRows) for the Python backend. Uses hand-rolled WebSocket over raw TCP (same approach as Rust) with socket.dup() for read/write split and a dedicated reader thread per connection. No external dependencies — just stdlib socket, hashlib, base64, struct, threading. Terminal size uses shutil.get_terminal_size(). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Check readyState before calling send(), and wrap in try/catch to prevent synchronous throws from crashing the server when a client disconnects mid-broadcast. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
114c6e7 to
936910d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add WebSocket support to Temper's standard library with 6 @connected functions (wsListen, wsAccept, wsConnect, wsSend, wsRecv, wsClose) and 2 opaque types (WsServer, WsConnection). Wired for JS (ws npm package) and Rust (tungstenite crate) backends.
Also adds terminalColumns() and terminalRows() to std/io for detecting terminal dimensions at runtime.