- worker DB builtins marshal to shard 0: requester-side slot encode (VM heaps never read cross-shard), owner executes serialized in adopt, reply unparks via new WO_PARK_INBOX park + envelope 3/4 - engine gains thread-agnostic slot entry points (insert_slots, update_field_slot, val_encode/clone, wo_db_exec_req); traps and messages byte-identical to the local path - main.c: engine + replay boot BEFORE shards spawn; workers assert rt.db/rt.wal NULL; busy shard adopts inbox once per slice - latent stage-1 bug fixed: shared io_uring params static raced by lazy worker init lost park wakes (~1/20 hangs); params per-vm, short submit now fails loud - new sample docs/examples/db-actor + just db-actor gate 8/0 (multi x3, uring/epoll forced, single byte-exact, WAL replay pair); ASan+TSan 6/6; full battery green Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
72 lines
2.6 KiB
Bash
Executable file
72 lines
2.6 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# scripts/db-actor-accept.sh — arc stage 3's gate: actors on worker shards
|
|
# read and write the database through the transparent DB actor. Multi-shard
|
|
# output is asserted as a SET (scheduling orders the writer lines); the
|
|
# main line and the single-shard run are exact. The WO_DATA pair proves a
|
|
# worker's write rides the owner's WAL and replays.
|
|
set -uo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
WOC="$ROOT/compiler/_build/default/bin/woc"
|
|
WOVM="$ROOT/runtime/wovm"
|
|
DIR="$ROOT/docs/examples/db-actor"
|
|
|
|
pass=0; fail=0
|
|
ok() { echo "ok $1"; pass=$((pass + 1)); }
|
|
bad() { echo "FAIL $1 -- $2"; fail=$((fail + 1)); }
|
|
|
|
if [[ ! -x "$WOC" || ! -x "$WOVM" ]]; then
|
|
echo "db-actor-accept: build woc and wovm first" >&2; exit 1
|
|
fi
|
|
|
|
if "$WOC" build "$DIR" -o "$DIR/target/db-actor" --runtime "$WOVM" >/dev/null 2>&1; then
|
|
ok "builds"
|
|
else
|
|
bad "build" "woc failed"; echo "db-actor-accept: 1 checks, 1 failures"; exit 1
|
|
fi
|
|
|
|
check_set() { # name [env pairs...]
|
|
local name="$1"; shift
|
|
local out
|
|
out="$(env "$@" timeout 30 "$DIR/target/db-actor" 2>&1)"
|
|
if printf '%s' "$out" | grep -q "writer 1 sees sum" \
|
|
&& printf '%s' "$out" | grep -q "writer 2 sees sum" \
|
|
&& printf '%s' "$out" | grep -q "^main sees 2 rows, sum 3$" ; then
|
|
ok "$name: both writers wrote and read cross-shard; main exact"
|
|
else
|
|
bad "$name" "$(printf '%s' "$out" | tr '\n' '|')"
|
|
fi
|
|
}
|
|
|
|
# multi-shard (default = all cores): the RPC path under test, three rounds
|
|
check_set "multi #1"
|
|
check_set "multi #2"
|
|
check_set "multi #3"
|
|
# forced backends: the reply park is plane-independent
|
|
check_set "multi uring" WO_IO=uring
|
|
check_set "multi epoll" WO_IO=epoll
|
|
|
|
# single-shard: byte-exact — the local path is untouched
|
|
sout="$(WO_SHARDS=1 timeout 30 "$DIR/target/db-actor" 2>&1)"
|
|
want=$'writer 1 sees sum 1\nwriter 2 sees sum 3\nmain sees 2 rows, sum 3'
|
|
if [[ "$sout" == "$want" ]]; then
|
|
ok "single-shard byte-exact"
|
|
else
|
|
bad "single-shard" "$(printf '%s' "$sout" | tr '\n' '|')"
|
|
fi
|
|
|
|
# durability through the RPC: a worker's insert commits on the owner's WAL
|
|
# before the ack; a restart replays it (2 rows, then 2+2)
|
|
DATA="$(mktemp -d)"
|
|
r1="$(WO_DATA="$DATA" timeout 30 "$DIR/target/db-actor" 2>&1 | tail -1)"
|
|
r2="$(WO_DATA="$DATA" timeout 30 "$DIR/target/db-actor" 2>&1 | tail -1)"
|
|
rm -rf "$DATA"
|
|
if [[ "$r1" == "main sees 2 rows, sum 3" && "$r2" == "main sees 4 rows, sum 6" ]]; then
|
|
ok "WAL: worker writes ack-after-durable, replay doubles the store"
|
|
else
|
|
bad "WAL replay" "r1=$r1 r2=$r2"
|
|
fi
|
|
|
|
echo
|
|
echo "db-actor-accept: $((pass + fail)) checks, $fail failures"
|
|
[[ $fail -eq 0 ]] || exit 1
|