igneum/tools/lock/with-lock.sh
igneum-labs 84c64d7aa3 Build and measurement lock for agents on the Mac; the standing rule in CLAUDE.md
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-04 16:58:56 +00:00

30 lines
1.3 KiB
Bash
Executable file

#!/usr/bin/env bash
# Serialises the two things that must not overlap on this Mac: BUILDS (cargo, swiftc, zigbuild, large cross-compiles) and
# MEASUREMENTS (test networks, hash-rate samples, simulators, anything whose numbers go in the bench log).
# tools/lock/with-lock.sh build <command...> one build at a time (builds also nice -n 19, 4 jobs)
# tools/lock/with-lock.sh measure <command...> one measurement at a time, and no build may start meanwhile
# Rule (4 October 2026): code and documents run in parallel; builds and measurements queue. Waits up to 2 hours.
set -euo pipefail
kind="$1"; shift
dir=/tmp/igneum-locks; mkdir -p "$dir"
case "$kind" in
build) locks=("$dir/build");;
measure) locks=("$dir/measure" "$dir/build");;
*) echo "usage: with-lock.sh build|measure <command...>" >&2; exit 2;;
esac
fds=(); i=9
for l in "${locks[@]}"; do
i=$((i+1)); eval "exec $i>\"$l\""
if ! python3 - "$i" "$l" <<'PY'
import fcntl, sys, time, os
fd=int(sys.argv[1]); name=sys.argv[2]; t=time.time()
while True:
try: fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB); break
except BlockingIOError:
if time.time()-t > 7200: print(f"with-lock: gave up waiting for {name} after 2 h", file=sys.stderr); sys.exit(1)
time.sleep(5)
PY
then exit 1; fi
done
echo "with-lock: holding ${locks[*]##*/} for: $*" >&2
exec "$@"