diff --git a/.gitignore b/.gitignore index de2009aa..99f6ec9e 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,7 @@ test-case-define.txt test_all.js test_final.js test_interactive.js + +# Loop lock/log state +.loop-locks/ +.loop-logs/ diff --git a/scripts/loop-guard.sh b/scripts/loop-guard.sh new file mode 100755 index 00000000..c170c6a4 --- /dev/null +++ b/scripts/loop-guard.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +set -euo pipefail + +LANG=${1:?usage: loop-guard.sh } +ROOT=$(cd "$(dirname "$0")/.." && pwd) +cd "$ROOT" +mkdir -p .loop-locks .loop-logs +LOCK=".loop-locks/$LANG.claim" +LOG=".loop-logs/$LANG.ndjson" +NOW=$(date +%s) +ISO=$(date -Iseconds) +STALE_SEC=${LOOP_STALE_SEC:-1800} + +if [ -f "$LOCK" ]; then + LAST=$(cat "$LOCK" 2>/dev/null || echo 0) + AGE=$((NOW - LAST)) + if [ "$AGE" -lt "$STALE_SEC" ]; then + printf '{"ts":"%s","lang":"%s","status":"skip","age":%d}\n' "$ISO" "$LANG" "$AGE" >> "$LOG" + echo "SKIP: $LANG claimed ${AGE}s ago (stale threshold ${STALE_SEC}s)" + exit 1 + fi + echo "INFO: $LANG lock was ${AGE}s old, overtaking" +fi + +echo "$NOW" > "$LOCK" +printf '{"ts":"%s","lang":"%s","status":"claimed"}\n' "$ISO" "$LANG" >> "$LOG" +echo "OK: $LANG claimed at $ISO" diff --git a/scripts/loop-release.sh b/scripts/loop-release.sh new file mode 100755 index 00000000..eb56e970 --- /dev/null +++ b/scripts/loop-release.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -euo pipefail + +LANG=${1:?usage: loop-release.sh } +STATUS=${2:-done} +ROOT=$(cd "$(dirname "$0")/.." && pwd) +cd "$ROOT" +LOCK=".loop-locks/$LANG.claim" +LOG=".loop-logs/$LANG.ndjson" +ISO=$(date -Iseconds) +rm -f "$LOCK" +printf '{"ts":"%s","lang":"%s","status":"released","exit":"%s"}\n' "$ISO" "$LANG" "$STATUS" >> "$LOG" +echo "OK: $LANG released ($STATUS)"