OverviewFilesCommitsIssuesDocsReleasesPeers

keet-daemon commits / 38572eb

design: R3 design + R3a done (drivers on rt, tick-driven monitor gate)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
38572eb59a5c5e6dfde0c720eddb0baf44dd9932
by plankatron <fleeky@gmail.com> · 2026-10-05T00:28:44.000Z

Changed files (1) +60 -0

docs/CPP-PORT-DESIGN.md +60 -0
……@@ -3229,6 +3229,66 @@ injected per layer:
32293229 write calls `refresh()`; a dropped TimeoutRefresh clears in its destructor.
32303230- **R3:** mux / replicator / Core onto `rt` (Clock, `onsettimeout`, `Host::defer`,
32313231 `resumeVia_` removed). All repl / store / core gates and every drill re-run.
3232- **R3 DESIGN (2026-10-04).**
3233 - **Seams removed:**
3234 - `repl::Clock` and its eight test/tool clocks (Test, Loop, Still, Null, Virtual, Fake…);
3235 - `Core::onsettimeout`;
3236 - `mux::Host::defer` and `Protomux::defer`;
3237 - `Replicator::resumeVia_`.
3238 - **Libraries call `rt` exactly where the JS calls the runtime:**
3239 - replicator: request timeout `setTimeout(onrequesttimeout, ms)`; `await backoff()` =
3240 `setTimeout(resolve, sleep)`; `_notDownloadingTimer` = `setTimeout` + `unref()`;
3241 `Date.now()` → `rt::now()`;
3242 - session-state recovery: `await setTimeout(5000 / 250)` → `rt::setTimeout` (JS awaits it
3243 in session-state itself, not through the replicator);
3244 - corestore gc: `setInterval(gcCycle, 2000).unref()`. protomux-wakeup gc: `setInterval`,
3245 as JS. speedometer: the module's `setInterval(inc, 250).unref()` tick counter, ported
3246 as is. hyperblobs monitor: `Date.now()`;
3247 - protomux: `queueTick` → `rt::queueMicrotask`; `Promise.resolve` → a microtask;
3248 safety-catch's async rethrow → a real throw in a microtask (rt's held-throw rule);
3249 - replicator waiters (`resumeVia_`) and autobee-wakeup (`muxer->defer`) →
3250 `rt::queueMicrotask`.
3251 - **Drivers.** A shared `tools/rt-harness.h` provides:
3252 - `act(fn)` — `rt::callback`;
3253 - `runUntil(ms, pred)`;
3254 - `ChildWatch` — `uv_poll` on a child's stdout, listener and frame socket, each event
3255 entering through `rt::callback`.
3256
3257 Who moves where:
3258 - pipe tests (m3c, m4c, wakeup ×2, blobs monitor) and the keetd-replicate / keetd-store
3259 tools → rt REAL;
3260 - trace tools (core-ops, store-ops, blobs-ops, bee-read, m4d appender) → rt VIRTUAL.
3261 store-ops' timed ops (`gc` waits N s; a 300 ms ready race) become loop waits.
3262 - **Order, each step gated:**
3263 - **R3a:** drivers onto rt behind ADAPTERS (a Clock over rt, `defer` = `rt::queueMicrotask`).
3264 Gate: ctest.
3265 - **R3b:** seams removed, faithful timers as above. Gate: ctest plus every m3c-era drill
3266 (m5g1*, m5g2*, m5g3e3, m5g4e1/e2, m5f*).
3267 - **R3c:** what rt newly makes portable: `RandomIterator` (`rt::random` = `Math.random`)
3268 and `queueUpdateAll`'s ≥ 40-peer path with `_updateAllBump`
3269 (`setTimeout(updateAll, getUpdateAllDelay)`). Gate designed when R3b is done.
3270 - **NOT R3 (R4):** every `await` — `seeker.update`, storage, and `yieldToLoop` (it needs the
3271 same continuation-style `_updateNonPrimary`).
3272- **R3a DONE 2026-10-04** (keetd 4cf2283). Every driver runs on rt; ctest 69/69.
3273 - **Pipe tests:** the old poll-loop body became the event step. m3c went from 182 s to 91 s.
3274 - **Trace tools:** on the virtual runtime.
3275 - **keetd-replicate / keetd-store:** rt is stepped on the transport's loop thread until 4e-4.
3276 M3d G1 passes, the same as the baseline.
3277 - `rt::runOnce()` added.
3278 - **Speedometer, ported ahead of R3b:** the module's `setInterval(inc, 250).unref()` with
3279 `setIntervalOverride`.
3280 - **The blobs-monitor gate's ticks are the script's (user decision):**
3281 - why: its speeds came from wall-clock 250 ms ticks across processes. The old driver passed
3282 unloaded only because its per-step overrun kept events off tick boundaries; it failed 5/8
3283 under load. Aligning the script to an exact schedule failed 8/8 (events land ON the
3284 boundaries). Both the JS peer and keetd capture the one setInterval, and the driver advances
3285 `ms / 250` ticks once every side is quiet;
3286 - result: 16/16, including under load;
3287 - **Harness trap:** never close an fd a uv_poll watches. Child::onAccept / onRelease let go of
3288 the fd first; a step's `read_frames` → `try_accept` closed a polled listener, and libuv
3289 aborted with EEXIST.
3290 - **Pre-existing, measured:** under heavy load s19 sometimes misses the JS uploader's "received"
3291 report (old 3/10, new 4/10; the JS-only control fails too).
32323292- **R4:** storage, per the decision above.
32333293- **Then 4e-4** (`createProtocolStream` / `replicate`): the first gate that composes the stack
32343294 is a COMPOSED trace against JS (secret-stream + protomux + replicator), now meaningful.