Documentation for Redweb 0.13.2. Install that exact version when following these examples.
Multiplayer production-readiness contract
Redweb remains a small transport foundation. Applications own game rules, authoritative state, matchmaking, databases, and identity providers. Redweb owns bounded connection admission, delivery, grouping, lifecycle, and optional composition points.
Compatibility invariants
- Every production feature is opt-in.
- Existing route, handler, and service subclasses require no source changes.
- The default route, strict routing, IP collision policy, handler dispatch, error hiding, listener ownership, and shutdown behavior remain compatible with 0.8.
- Disabled multiplayer features create no timers or per-connection queues.
- No global mutable registry or mandatory infrastructure dependency is permitted.
- Every timer, listener, queued task, membership, session lease, and adapter subscription has one deterministic cleanup owner.
- User hooks may be synchronous or asynchronous and may not escape as process-level failures.
- Cleanup is bounded, idempotent, best-effort, and continues after individual failures. Owned listeners also terminate incomplete HTTP peers at the route deadline; borrowed listeners remain application-owned.
Delivery claims
WebSocket provides an ordered byte stream while a connection remains healthy. Redweb does not claim exactly-once delivery. Reconnection, distributed adapters, and application retries can introduce loss or duplication; protocol users must use explicitly scoped sequence identifiers when those cases matter.
Roadmap gates
- Bounded transport: pre-upgrade admission, origin policy, rate limits, slow-consumer enforcement, bounded ordered processing, payload limits, and route-level heartbeat.
The first observation of heartbeat expiry starts one unreferenced timeoutMs
grace timer, allowing already-dispatched pong handling to win after a server
stall; a peer that remains silent is terminated when that timer fires. Pong,
detach/reattach, and shutdown cancel the owned timer.
timeoutMs is therefore a liveness threshold subject to event-loop scheduling,
not a hard wall-clock resource limit. The grace period owns at most one timer
per expired connection; bound connections and queues independently.
2. Multiplayer grouping: route-scoped rooms, atomic membership cleanup, bounded session resumption, fixed-step services, and vendor-neutral metrics.
3. Horizontal composition: draining/readiness, adapter lifecycle, loop prevention, bounded validation, placement hooks, and documented partition behavior.
4. Protocol and clients: version negotiation, stable envelopes and error codes, generated client-facing types, binary replication hooks, and operational examples.
Release gates
- Existing tests and documented examples run unchanged.
- New behavior has unit tests and mock-free HTTP/WS/WSS integration tests.
- Coverage remains 100% for statements, branches, functions, and lines.
- Disabled-feature throughput regression is at most 3%; p99 latency regression is at most 5% on the same machine and Node version.
- Heartbeat uses one scheduler per route, never one interval per connection.
- Every queue, retained session, room, adapter backlog, and deduplication window is finite.
- Broadcast serializes once and remains O(n) in selected recipients.
- Slow clients cannot grow framework-owned memory without bound.
- A 60-minute soak shows no monotonic growth in timers, listeners, rooms, sessions, or queues.
- The blocking
server-steady-v1reconnect gate requires every storm to retain at most 110% of the same warmed server heap after expiry and forced collection. Exact delivery, empty measured registries, unchanged inputs, complete logs and normal worker cleanup are mandatory. Client heap is reported separately; the original shared-process diagnostic remains visible and non-blocking, without relabelling its failures. - Readiness becomes false before draining and shutdown completes within its documented bound.
The independent senior-review gate rejects releases that weaken any invariant, hide ambiguous delivery semantics, add mandatory brokers or identity libraries, or substitute coverage percentages for race, load, soak, and failure evidence.
See operations verification for the current commands and the distinction between server acceptance and the original diagnostic. These are required gates, not a statement that every release has passed them; consult the version's release checklist for recorded results and remaining limitations.
Horizontal composition contract
- Placement runs before upgrade within the admission timeout. Redirects must use
wss, contain no credentials or fragment, and may be restricted withallowedPlacementOrigins. Plainwsplacement requires the explicitallowInsecurePlacementescape hatch for private development networks. - Readiness becomes false before shutdown work begins. New upgrades receive
503; existing connections stop accepting messages. drainHandlersis opt-in. When enabled, every connection context shares the route drain signal and shutdown awaits tracked work. Application handlers remain responsible for observing the signal; non-cooperating promises cannot be forcibly cancelled.- Distribution adapters have no framework backlog. Publish and inbound concurrency are finite; publish failure returns
false; startup, subscription, unsubscription, draining, and close are bounded. Adapter operations receive an optionalAbortSignal, and late startup/subscription settlement is compensated. Adapters must observe the signal when their external side effects are not otherwise reversible. - A failed publish marks a
requiredadapter unhealthy, makes the route unready, and causes new upgrades to receive503; a later successful publish restores health. Best-effort adapters do not affect route readiness. - Event IDs are deduplicated only inside a finite TTL/size window. Source-node events are ignored to prevent reflection loops.
- Broker partitions and process failure can lose events. Redweb makes no exactly-once or durable-delivery claim; applications own authoritative persistence, reconciliation, tick/sequence semantics, and partition policy.
Protocol contract
- Negotiation is opt-in and happens before upgrade. Unsupported clients receive
426plus the finite supported-version list. - JSON events use
{ v, type, payload, requestId?, sequence? }. Error events use{ v, type: "error", error: { code, message }, requestId? }. requestIdcorrelates a request and response;sequenceexpresses application ordering. Neither implies acknowledgement, durability, or exactly-once delivery.- Stable framework codes are generated from
src/ws/protocol-schema.json; the client declarations and runtime constants share that source. - Binary replication is a codec hook, not a codec dependency. Size is checked before decode and after encode, and outbound data uses the normal backpressure ceiling.
- Protocol-disabled routes retain their 0.8 wire shapes and allocate no protocol context.
Resource ownership
maxPendingUpgradesbounds authorization work before a socket is accepted.- Timed-out admission hooks that ignore cancellation retain their reservation until they actually settle, preventing repeated timeout waves from accumulating unbounded application work.
- Fixed-step services clamp retained lag with
maxRetainedLagMs; dropped time is observable rather than replayed forever. - Session count, ID length, and lifetime are bounded by Redweb. Session
datais application-owned, so applications must validate and cap its shape and byte size before storing it. - Fully enabled idle routes have a 2 KiB framework-metadata budget per connection. Disabled features retain the legacy path; the performance gate compares against an explicitly prepared, identified release baseline. Historical 0.8 evidence does not establish performance against a newer baseline.