Files
hack-house/cmd_chat/server/helpers.py
T
leetcrypt 3a54578f0a perf(net): near-real-time sandbox for non-host viewers
Two causes made a shared shell's PTY stream lag for non-host viewers and
then arrive "all at once":

1. Nagle's algorithm — PTY echo/keystrokes/chat are tiny frames; Nagle +
   delayed-ACK (amplified by Tailscale RTT) coalesced them into bursts.
   Set TCP_NODELAY on the client websocket (Plain/--no-tls path) and on
   each server connection's socket (via ws.io_proto.transport).

2. Head-of-line blocking — ConnectionManager.broadcast awaited each
   send() serially under a global lock, so the slowest viewer gated
   delivery to everyone AND stalled the server's read of the broker's
   next frame, backing the stream up. Give each connection its own
   bounded outbound queue + writer task; broadcast now only enqueues and
   never waits on a socket. A peer that overflows its backlog (4096) is
   evicted (close 1013) and resyncs on reconnect rather than buffering
   without bound or being fed a gapped terminal stream. Init snapshot is
   enqueued as the guaranteed-first frame (send_state -> state_frame).

Adds tests/test_manager.py (FIFO, slow-client isolation, wedged
eviction, reconnect replacement). Also fmt-clean sbx.rs/theme.rs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-06 17:11:51 -07:00

58 lines
1.9 KiB
Python

import os
import time
from collections import defaultdict
from datetime import datetime, timezone
from dataclasses import asdict
import json
from sanic import Request, Sanic, Websocket
def utcnow() -> datetime:
return datetime.now(timezone.utc)
# Only honor X-Forwarded-For when explicitly told we sit behind a trusted proxy
# (TRUST_PROXY=1). Otherwise a direct client can spoof the header to forge a
# source IP and dodge the per-IP rate limiter, so we use the real peer address.
_TRUST_PROXY = os.environ.get("TRUST_PROXY", "").lower() in ("1", "true", "yes")
def get_client_ip(request: Request) -> str:
if _TRUST_PROXY:
if forwarded := request.headers.get("x-forwarded-for"):
return forwarded.split(",")[0].strip()
return request.ip
def state_frame(app: Sanic) -> str:
"""Build the per-client `init` snapshot (message backlog + roster) as a JSON
string. Returned (not sent) so it can be enqueued as the connection's first
outbound frame, guaranteeing it precedes any later broadcast."""
messages = app.ctx.message_store.get_all()
users = app.ctx.session_store.get_all()
return json.dumps(
{
"type": "init",
"messages": [asdict(m) for m in messages],
"users": [
{"user_id": u.user_id, "username": u.username} for u in users
],
}
)
class RateLimiter:
def __init__(self, max_requests: int = 10, window_seconds: int = 60):
self.max_requests = max_requests
self.window = window_seconds
self._requests: dict[str, list[float]] = defaultdict(list)
def is_allowed(self, key: str) -> bool:
now = time.monotonic()
timestamps = self._requests[key]
timestamps[:] = [t for t in timestamps if now - t < self.window]
if len(timestamps) >= self.max_requests:
return False
timestamps.append(now)
return True