Repository navigation
conference: reliable roster re-broadcast (fixes browser 'can't see each other') + scene roadmap - #757
Merged
Merged
Conversation
…st; scene roadmap The WS relay re-fans a client's join to already-connected peers once, with no retry, so a join that races an established peer's socket can be missed at low traffic (the single-threaded browser's weak spot) and never recover. Add state_transport_ws::broadcast_snapshot() and call it ~once a second from arisrv's loop so every client idempotently re-converges on the room (and later scene) tree. Verified live: two browser tabs on cyberpcangel.com/cyprty see each other (an established client picks up a late joiner), and native WS clients over the internet. Also roadmap §5g: the server-authoritative shared 3D scene tree (conf.rooms.<room>.scene.*) that all clients render from their own camera, plus per-participant avatar pose, recorded as next work.
…tall the roster The relay fans video + state to each client over one connection with synchronous writes. Under a live conference's continuous video, a client that can't drain fast enough fills its OS send buffer and ws->write() blocks on it — and because the ~1s roster re-broadcast runs in one loop, blocking on ONE slow client stalls roster delivery (join/leave) for EVERY client. Observed live: a fast probe got the join snapshot but never saw a later join-once peer on the loaded relay, yet did instantly on an idle one. Add connection::send_backlog() (SIOCOUTQ, Linux) and, before each fan write, skip a backed-up peer: drop the loss-tolerant media frame above ~128KB queued, and defer the (reliable, retried-next-tick) mutation/broadcast writes above ~512KB. State is never starved by video; a slow peer drops invisible video frames instead of freezing everyone's roster. Verified under live browser-tab load: an established client now picks up a late join-once joiner, and a throttled background tab converges too.
Three compounding bugs left deployed clients unable to see each other's name or camera once real video was flowing: 1. Relay deferred the roster broadcast behind the video flood. Drop media hard (>32KB send backlog) to keep a peer's buffer tiny, and only defer a state write at 2MB — i.e. for an effectively-dead socket, never a merely-loaded one. Validated: 5 clients cross-fanning video, roster delivered to all every tick (wrote=5 skipped=0) while ~27% of video is shed. Env-gated CVC_WS_BROADCAST_DEBUG per-tick summary for observability. 2. Client roster collapsed to empty. The ari per-frame reactive budget (10ms) was exhausted mid-roster under wasm video decode, so the repeat-count expr (peer.count) fail-safed to 0 and the whole participant list + peer camera windows vanished that frame. Raise the budget to 30ms (clears ~6-7 peers) and cache the last-good repeat count so a transient skip can never blank a repeated list. 3. Peer camera windows all stacked at one authored pos. Pre-seed each cam_<i> geometry into a 2-column grid right of the Users window, so the roster is never covered and up to four cameras show side-by-side. Also seed peer.count="0" at host init so the roster's repeat count is a valid integer from frame 0 (no startup "did not yield an integer" warn). cyprty: V -> cyprty-ui6.
… kills on_tick) On the browser real-camera path the roster was always empty — no peers, no names, no cameras, stale peers that never cleared — while synthetic test clients worked. Root cause: state-get on an UNSET node returns nil (not ""), and the on_tick's real-camera-only device-switch block guards with (= cam.want_device ""), which is false for nil. So before the host first populates that field the block runs and evaluates (int nil), which throws — and a throw in the resident on_tick handler kills it permanently, so the roster-build never runs. Synthetic clients skip the whole block (cam_synthetic=1), which is why the bug was invisible in every synthetic test. Fix: seed cam/mic.want_device and cam/mic.cur_device to "" in run_init, so the guard is correct (= "" "") and the block is skipped until a real device switch is requested. Verified by reproduction: two real-camera-path clients that showed a blank "in the room:" before now show "in the room: 2" and list each other. cyprty: V -> cyprty-ui7.
…riadne DSL roadmap
Extends §5g with the holon architecture the design discussion scoped:
- §5h — the holon = {world_clock + physics(Jolt) + scene/pose} as a server-
authoritative, client-replicable, composable unit: frame-loop driver, client
prediction + reconcile, pose propose/veto/override, spatial-interest + geometry
LOD (landed) + physics LOD (new), subdelegation/holarchy on the lease manager,
cross-node clock sync, with data() object replication (DISTRIBUTED_STATE §52) as
the leading prerequisite. Phasing H0-H4.
- §5i — the DSL as a first-class read+write holon participant: client mods
(local + propose), server/admin authoritative scripts, and cross-injection under
a capability grant (intrinsics allowlist / state chroot / channel scoping /
resource limits — all existing enforced primitives). Phasing D1-D4, threat model
first.
- §10 — baseline-shipped note (cyprty live on the WS-relay path; holon/DSL is the
next arc).
- §13 — consolidates the (substantially complete) Ariadne cvcGL UI/scene DSL
roadmap: near-term fold-ins (input_text, multi-view §9.5 -> H1, light node, HTTP
cache, async-scheduler parity), backlog retained (TF editor, JSON-Schema
validator, s-expr dialect, program modularity, pycvc URI), and a stale-doc
refresh (geometry LOD landed PR #249+, tvision + EGL harness done).
Docs only; no code change.
…code, not the stale doc The first §13 pass trusted a doc-audit of CVCGL-UI-DSL-ROADMAP.md, which is badly stale. Verified against the tree instead: input_text/input_int (loader.cpp:650, #636), RenderView/VisibilityMask (RenderView.cpp), light node (LightNode.cpp), clipboard (Clipboard*.cpp), async-scheduler parity (receive_message/sleep/ yield_frame in async_scheduler.cpp), and the JSON-Schema validator integration are ALL landed — not gaps. §13 now lists verified-landed vs genuinely-remaining (TF editor §10 and program modularity §19 have no code; the rest need per-item code checks), and flags that even this file's §9/§10 are stale on input_text. Also fixed §5h H1 to USE the existing RenderView rather than "pull it in". Docs only.
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.
Reliability fix (deployed)
The WS relay re-fanned a new client's join to established connections only once, with no retry, so at low traffic a late joiner could be missed by an established client and never recover — the browser 'clients can't see each other' report. (The name-collision interest filter was innocent; confirmed by disabling it.)
Fix:
state_transport_ws::broadcast_snapshot()re-pushes the full room snapshot to every connection; arisrv calls it ~1s in its loop so every client idempotently re-converges. Verified live with two browser tabs on cyberpcangel.com/cyprty (established client picks up a late joiner) and native WS clients over the internet. Already deployed to the paladin relay.Roadmap §5g (next work)
Server-authoritative shared 3D scene tree (
conf.rooms.<room>.scene.*) every client renders from its own camera, + per-participant avatar pose. Scene-tree implementation + the UI fixes (Set button, flashing, browser aspect ratio) land next.