Created
August 11, 2026 19:02
-
-
Save K-Mistele/a23fbbff713a82799c517abbc78408ca to your computer and use it in GitHub Desktop.
Reproduce Rivet actor destroy retaining branch-backed SQLite data
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
| #!/usr/bin/env bash | |
| set -euo pipefail | |
| dir="$(mktemp -d)" | |
| project="rivet-sqlite-destroy-repro" | |
| trap 'docker compose -p "$project" -f "$dir/compose.yml" down -v --remove-orphans >/dev/null 2>&1 || true; rm -rf "$dir"' EXIT | |
| cat >"$dir/package.json" <<'EOF' | |
| {"private":true,"type":"module","dependencies":{"rivetkit":"2.3.10"}} | |
| EOF | |
| cat >"$dir/server.ts" <<'EOF' | |
| import { actor, setup } from "rivetkit" | |
| const probe = actor({ | |
| state: { marker: "" }, | |
| actions: { | |
| seed: (c, marker: string) => { | |
| c.state.marker = `${marker}:${"x".repeat(262_144)}` | |
| }, | |
| }, | |
| }) | |
| setup({ use: { probe }, sqlite: "remote", noWelcome: true }).start() | |
| EOF | |
| cat >"$dir/create.ts" <<'EOF' | |
| import { createClient } from "rivetkit/client" | |
| const client = createClient("http://default@engine:6420") | |
| const handle = client.probe.getOrCreate(["destroy-repro"]) | |
| await handle.seed("survives-destroy") | |
| await Bun.write("/shared/actor-id", await handle.resolve()) | |
| EOF | |
| cat >"$dir/Dockerfile" <<'EOF' | |
| FROM oven/bun:1.3.14-alpine | |
| WORKDIR /app | |
| COPY package.json ./ | |
| RUN bun install --production | |
| COPY server.ts create.ts ./ | |
| CMD ["bun", "server.ts"] | |
| EOF | |
| cat >"$dir/compose.yml" <<'EOF' | |
| services: | |
| postgres: | |
| image: postgres:17-alpine | |
| environment: | |
| POSTGRES_DB: rivet | |
| POSTGRES_USER: rivet | |
| POSTGRES_PASSWORD: rivet | |
| healthcheck: | |
| test: ["CMD-SHELL", "pg_isready -U rivet -d rivet"] | |
| interval: 2s | |
| timeout: 5s | |
| retries: 30 | |
| engine: | |
| image: rivetdev/engine:latest | |
| command: ["start"] | |
| environment: | |
| RIVET__POSTGRES__URL: postgresql://rivet:rivet@postgres:5432/rivet | |
| ports: | |
| - "16420:6420" | |
| depends_on: | |
| postgres: | |
| condition: service_healthy | |
| healthcheck: | |
| test: ["CMD", "curl", "-f", "http://127.0.0.1:6421/health"] | |
| start_period: 30s | |
| interval: 2s | |
| timeout: 5s | |
| retries: 30 | |
| configure: | |
| image: curlimages/curl:8.12.1 | |
| command: | |
| - -f | |
| - -X | |
| - PUT | |
| - http://engine:6420/runner-configs/default?namespace=default | |
| - -H | |
| - "Content-Type: application/json" | |
| - -d | |
| - '{"datacenters":{"default":{"normal":{}}}}' | |
| depends_on: | |
| engine: | |
| condition: service_healthy | |
| app: | |
| build: . | |
| environment: | |
| RIVET_ENDPOINT: http://default@engine:6420 | |
| volumes: | |
| - .:/shared | |
| depends_on: | |
| configure: | |
| condition: service_completed_successfully | |
| EOF | |
| dc=(docker compose -p "$project" -f "$dir/compose.yml") | |
| "${dc[@]}" up -d --build | |
| "${dc[@]}" exec -T postgres psql -U rivet -d rivet -v ON_ERROR_STOP=1 <<'SQL' >/dev/null | |
| CREATE TABLE branches_before AS | |
| SELECT DISTINCT substring(key FROM 4 FOR 16) AS branch_id | |
| FROM kv | |
| WHERE substring(key FROM 1 FOR 3) = decode('02302f', 'hex'); | |
| SQL | |
| "${dc[@]}" exec -T app bun create.ts | |
| actor_id="$(<"$dir/actor-id")" | |
| branch_hex="$("${dc[@]}" exec -T postgres psql -U rivet -d rivet -Atc " | |
| SELECT encode(branch_id, 'hex') | |
| FROM ( | |
| SELECT DISTINCT substring(key FROM 4 FOR 16) AS branch_id | |
| FROM kv | |
| WHERE substring(key FROM 1 FOR 3) = decode('02302f', 'hex') | |
| EXCEPT SELECT branch_id FROM branches_before | |
| ) branches; | |
| ")" | |
| if [[ ! "$branch_hex" =~ ^[0-9a-f]{32}$ ]]; then | |
| printf 'Expected exactly one new SQLite branch, got: %s\n' "$branch_hex" >&2 | |
| exit 1 | |
| fi | |
| measure() { | |
| "${dc[@]}" exec -T postgres psql -U rivet -d rivet -Atc " | |
| SELECT 'branch_rows=' || count(*) | |
| FROM kv | |
| WHERE substring(key FROM 1 FOR 19) = decode('02302f${branch_hex}', 'hex'); | |
| SELECT 'refcount=' || ( | |
| get_byte(value, 0)::bigint | |
| + (get_byte(value, 1)::bigint << 8) | |
| + (get_byte(value, 2)::bigint << 16) | |
| + (get_byte(value, 3)::bigint << 24) | |
| + (get_byte(value, 4)::bigint << 32) | |
| + (get_byte(value, 5)::bigint << 40) | |
| + (get_byte(value, 6)::bigint << 48) | |
| + (get_byte(value, 7)::bigint << 56) | |
| ) | |
| FROM kv | |
| WHERE key = decode('02202f6c6973742f${branch_hex}', 'hex') || convert_to('/refcount', 'UTF8'); | |
| " | |
| } | |
| printf '\nBefore destroy:\n' | |
| measure | |
| curl -fsS -X DELETE "http://127.0.0.1:16420/actors/${actor_id}?namespace=default" >/dev/null | |
| printf '\nAfter destroy:\n' | |
| measure |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment