Replication!
This commit is contained in:
1 parent
427a824e45
commit
3d819c7b10
6 files changed
+1004
-71
No files matched your search
Executable
+125
@@ -0,0 +1,125 @@
|
||||
#!/usr/bin/env bash
|
||||
# Starts a primary (:3000) and a replica (:3001), writes a few records to the
|
||||
# primary and checks that they show up on the replica.
|
||||
# Run from the project root: bash repl-test.sh
|
||||
# Override the binary with: BIN=/path/to/rust_test bash repl-test.sh
|
||||
set -euo pipefail
|
||||
|
||||
BIN="${BIN:-$(pwd)/target/debug/rust_test}"
|
||||
WORK="${WORK:-$(pwd)/repl-test}"
|
||||
TOKEN="${TOKEN:-dev-secret-token}"
|
||||
PRIMARY_PORT=3000
|
||||
REPLICA_PORT=3001
|
||||
|
||||
[[ -x "$BIN" ]] || { echo "Binary not found or not executable: $BIN" >&2; exit 1; }
|
||||
|
||||
# Each instance gets its own directory: messages.db is opened relative to cwd.
|
||||
rm -rf "$WORK"
|
||||
mkdir -p "$WORK/primary" "$WORK/replica"
|
||||
|
||||
for d in primary replica; do
|
||||
cat > "$WORK/$d/config.json" <<'EOF'
|
||||
{
|
||||
"mode": "loose",
|
||||
"fields": {
|
||||
"msg": { "type": "string" }
|
||||
}
|
||||
}
|
||||
EOF
|
||||
done
|
||||
|
||||
PIDS=()
|
||||
cleanup() {
|
||||
trap - EXIT INT TERM
|
||||
echo
|
||||
echo "Stopping instances..."
|
||||
for pid in "${PIDS[@]}"; do kill "$pid" 2>/dev/null || true; done
|
||||
wait 2>/dev/null || true
|
||||
}
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
start() { # name port extra-env...
|
||||
local name=$1 port=$2
|
||||
shift 2
|
||||
( cd "$WORK/$name" && exec env \
|
||||
APP_CONFIG=config.json \
|
||||
APP_BIND="127.0.0.1:$port" \
|
||||
APP_REPL_TOKEN="$TOKEN" \
|
||||
APP_SYNC_INTERVAL_SECS=1 \
|
||||
"$@" "$BIN" ) >"$WORK/$name/log.txt" 2>&1 &
|
||||
PIDS+=("$!")
|
||||
}
|
||||
|
||||
wait_up() { # port
|
||||
for _ in $(seq 1 50); do
|
||||
curl -sf "http://127.0.0.1:$1/api/now" >/dev/null 2>&1 && return 0
|
||||
sleep 0.1
|
||||
done
|
||||
echo "Instance on port $1 did not come up; see logs in $WORK" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
echo "Starting primary on :$PRIMARY_PORT"
|
||||
start primary "$PRIMARY_PORT" APP_ROLE=primary
|
||||
wait_up "$PRIMARY_PORT"
|
||||
|
||||
echo "Starting replica on :$REPLICA_PORT"
|
||||
start replica "$REPLICA_PORT" \
|
||||
APP_ROLE=replica \
|
||||
APP_PRIMARY_URL="http://127.0.0.1:$PRIMARY_PORT"
|
||||
wait_up "$REPLICA_PORT"
|
||||
|
||||
echo
|
||||
echo "Writing 3 records to the primary"
|
||||
for i in 1 2 3; do
|
||||
curl -s -X POST "http://127.0.0.1:$PRIMARY_PORT/api/records" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d "{\"data\":{\"msg\":\"hello $i\"}}"
|
||||
echo
|
||||
done
|
||||
|
||||
echo
|
||||
echo "Waiting for the replica to catch up..."
|
||||
caught_up=0
|
||||
for _ in $(seq 1 30); do
|
||||
if curl -s "http://127.0.0.1:$REPLICA_PORT/api/replication/status" \
|
||||
| grep -q '"last_applied_seq":3'; then
|
||||
caught_up=1
|
||||
break
|
||||
fi
|
||||
sleep 0.5
|
||||
done
|
||||
|
||||
echo
|
||||
echo "Replica status:"
|
||||
curl -s "http://127.0.0.1:$REPLICA_PORT/api/replication/status"
|
||||
echo
|
||||
echo
|
||||
echo "Replica records:"
|
||||
curl -s "http://127.0.0.1:$REPLICA_PORT/api/records"
|
||||
echo
|
||||
echo
|
||||
echo "Write to the replica (should be rejected):"
|
||||
curl -s -w ' [HTTP %{http_code}]\n' -X POST "http://127.0.0.1:$REPLICA_PORT/api/records" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"data":{"msg":"nope"}}'
|
||||
|
||||
echo
|
||||
if [[ $caught_up -eq 1 ]]; then
|
||||
echo "OK: replica caught up."
|
||||
else
|
||||
echo "WARNING: replica did not reach seq 3 in time; check $WORK/replica/log.txt"
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
|
||||
Both instances are still running. Try:
|
||||
curl -s -X POST http://127.0.0.1:$PRIMARY_PORT/api/records -H 'Content-Type: application/json' -d '{"data":{"msg":"more"}}'
|
||||
curl -s http://127.0.0.1:$REPLICA_PORT/api/replication/status
|
||||
Logs: $WORK/primary/log.txt and $WORK/replica/log.txt
|
||||
To test lazy sync: kill the primary (PID ${PIDS[0]}), write nothing, restart it by hand
|
||||
from $WORK/primary with the same env, and watch the replica recover.
|
||||
Ctrl-C to stop both.
|
||||
EOF
|
||||
|
||||
wait
|
||||
Reference in new issue
Block a user