ryu-realtime 0.1.2

Room-keyed realtime fan-out primitive for Ryu: a transport-agnostic RoomRegistry mapping room_id -> a per-room tokio actor that owns isolated ephemeral state (presence map + idle clock) behind a command channel, with a bounded broadcast sender for fan-out. Rooms are keyed by id, hibernate when idle, and rehydrate on next join; membership is an RAII guard whose Drop reaps presence. Exposes a typed event contract (the Frame enum over Events/Presence/DocSync channels, broadcast via publish_event, subscribe returning a droppable receiver = unsubscribe handle). An extracted Core capability crate consumed as a NON-optional in-process path dependency (the chat fan-out path drives it directly, never over IPC). ZERO dependency on apps/core.
Documentation

  ryu-realtime

Room-keyed realtime fan-out primitive for Ryu. Part of Ryu.

License Stack

ryu-realtime is the transport-agnostic fan-out core (Phase 1 of the multi-user collaboration epic) that chat fan-out, CRDT doc-sync, and presence/awareness all consume. It knows nothing about WebSockets, JWTs, or access control — those live in the Core WS handler that drives this registry.

Shape

  • RoomRegistry maps room_id → a RoomHandle. Each live room runs as one tokio actor task (run_room) that owns the room's ephemeral state (presence map + idle clock) behind a command channel, plus a bounded tokio::sync::broadcast sender for fan-out.
  • Membership is reference-counted; RoomHandle::join returns a RoomMembership RAII guard whose Drop decrements the count, evicts the member's presence, and broadcasts a presence_leave delta — so a dropped socket is still reaped.
  • Hibernation — a room idle beyond RoomConfig::idle_window exits its actor and leaves the registry, rehydrating on next join (the main scaling lever).
  • Race safety — join's get-or-create + fetch_add and the actor's eviction recheck take the same registry Mutex, so no caller ever holds a handle to a dropped room.
  • Typed event contract — the Frame enum over Event / Presence / DocSync channels; publish_event broadcasts, subscribe returns a droppable receiver (= unsubscribe handle).

Role in the decomposition

An extracted Core capability crate consumed as a non-optional in-process path dependency — the chat fan-out path drives it directly, never over IPC. ZERO dependency on apps/core; it is a sibling to Core's identity_verify. The WS transport and any access control are the swap-seam boundary and stay Core-side.

Placement (CLAUDE.md §1): fan-out of live session state is what runs, so Core.

Build

cargo build -p ryu-realtime
cargo test  -p ryu-realtime

License

Apache-2.0; see LICENSE. © 2026 A Major Pte. Ltd.