From 5e51a151c043aad830234289f64a946433b1f827 Mon Sep 17 00:00:00 2001 From: "shoney.arickathil" Date: Fri, 21 Aug 2026 13:16:36 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20CODE-LOGIC=20=E2=80=94=20DB-actor=20RPC?= =?UTF-8?q?=20+=20ring-params=20fix,=20slot=20surface?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- database/src/CODE-LOGIC.md | 18 ++++++++++++++++++ runtime/src/CODE-LOGIC.md | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/database/src/CODE-LOGIC.md b/database/src/CODE-LOGIC.md index ad5987e..119d1c0 100644 --- a/database/src/CODE-LOGIC.md +++ b/database/src/CODE-LOGIC.md @@ -61,3 +61,21 @@ rather than acknowledging what disk never got. - `just oop-e2e`, `just log-watcher` — regression that linking the engine into wovm changed nothing observable (it is dead code until Task 3 wires the first builtin). + +## The slot-level surface (arc stage 3, 2026-08-21) + +- **Why it exists:** the transparent DB actor executes a worker's + statement on the owner shard, and VM heaps are never read cross-shard — + so the requester encodes to engine slots on its own thread and the owner + executes from slots, exactly the shape WAL replay already used. +- `wo_db_val_encode` exposes the in-gate for the RPC marshaler; + `wo_db_val_clone` deep-copies an engine value (a get-field reply must + outlive the row: a later serialized statement may free the slot); + `wo_row_insert_slots` / `wo_row_update_field_slot` are the pre-encoded + twins of insert/update (slot values consumed either way — installed on + success, freed on failure); `wo_db_exec_req` (db.c) mirrors + `wo_builtin_db` case for case with slot inputs and plain outputs, so a + worker sees byte-identical traps and messages. +- The update refactor extracted `row_apply_field_slot` (the post-encode + half: unique shadow-check, index fix-up, slot swap) shared by both + entry points — the VM-value path's behavior is unchanged bit for bit. diff --git a/runtime/src/CODE-LOGIC.md b/runtime/src/CODE-LOGIC.md index b36d76f..9998986 100644 --- a/runtime/src/CODE-LOGIC.md +++ b/runtime/src/CODE-LOGIC.md @@ -181,3 +181,35 @@ layout. word and a Bytes as the same length-prefixed blob a Text uses, so replay is bit-exact for NaN, ±Inf, and `-0.0`. `test_wal`'s `test_float_bytes_replay` asserts on bits for exactly that reason. + +## The transparent DB actor (arc stage 3, 2026-08-21) + +- **The database is an actor on shard 0.** A worker shard's DB builtin + never touches an engine (its `rt.db` is NULL, asserted at serve entry): + `wo_db_rpc` (vm.c) marshals the statement, ships it in a kind-3 envelope + to the primary's inbox, and parks the fiber; the primary executes it + serialized inside its inbox drain (`wo_vm_adopt` case 3, `wo_db_exec_req`) + and ships the same request back as a kind-4 reply, which unparks the + fiber; the builtin RE-EXECUTES and consumes the answer. +- **VM heaps never cross shards.** The requester ENCODES its argument + values into engine slots on its own thread (`wo_db_val_encode`) — an + owner-side read of a requester's Text would race that shard's collector + writing header mark bits. Replies come back as plain ids (scan/probe), a + deep-cloned engine value (get-field, decoded into the requester's arena), + or a bare id (insert). Traps and messages are byte-identical to the local + path; the ack crosses shards only after the owner's WAL commit. +- **The reply park holds no plane wait.** `WO_PARK_INBOX` (park_fd -2) + joins the parked list only; the wake is `wo_io_unpark` from the envelope + drain. Deadline scans key on park_fd == -1 EXACTLY — a -2 must never be + read as a deadline. A busy shard adopts its inbox once per reduction + slice, so a computing primary bounds a worker's DB latency to one slice. +- **Ring params are per-vm (`wo_vm.io_params`) — never share them.** They + were one file static; a worker's lazy `wo_vm_init` memset+refilled it + while another shard read ring offsets out of it, submits landed at + garbage offsets, and parked fibers lost their wakes (~1/20 hangs at + default cores, found by stage 3's cross-shard traffic). A short + `io_uring_enter` submit is a failure, never a success — that check is + what turns any relapse into a loud WO_T_IO instead of a silent hang. +- Proof: `just db-actor` (docs/examples/db-actor — multi-shard set ×3, + both forced backends, single-shard byte-exact, WO_DATA replay pair); + ASan/TSan clean on the RPC path.