daniel/gitdan's ci-cache-reclaim.sh hard-codes four dot-prefixed names it reads to make correctness decisions but never reclaims as leftovers — .ci-lock-*, .cache-last-used, .gitea-last-used, .ci-keep — none of which carried a matching note here (gitdan#32, the follow-up shape to #28/#30 that #7/PR #8 covered for the leftover names specifically). Of the four, this repo actually produces two: - .ci-lock-<id>, written by scripts/cache-lock.sh (acquire/release) and cache-lib.sh's write_cache_lock(). Documents the contract at cache-lock.sh's header, the site someone renaming the marker would most likely be editing. - .cache-last-used, stamped every run by cargo-cache/action.yml. Documents the contract at the exact line that writes it. The other two are read by gitdan's script but produced by nothing in this repo: .gitea-last-used is a legacy naming convention individual repos used before adopting the shared cargo-cache action (nothing here writes it today), and .ci-keep is a per-repo, hand-placed opt-out any consuming repo's own workflow may drop directly into a cache directory, with no single owner. Both get a paragraph in README.md's new subsection explaining why no producer-side counterpart exists for them, rather than inventing an owner this repo doesn't have. README.md's "Scratch names in a cache root are a cross-repo contract" section gains a new subsection, "Names this repo doesn't reclaim, but the arbiter depends on", covering all four and pointing at gitdan's DEPENDED-UPON NAMES CONTRACT block as the canonical description. No behaviour change: comments and docs only. Ref: gitdan#32. Consumer-side counterpart: daniel/gitdan (this branch's sibling PR). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MJHKJFJVUjnvVsemVBnvrd
50 lines
2.2 KiB
Bash
Executable File
50 lines
2.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Marks a cache directory as held open by a running job, so ANY job's prune
|
|
# pass (including this run's own) skips it.
|
|
#
|
|
# Usage: cache-lock.sh acquire|release <dir> <lock-id>
|
|
#
|
|
# Without this, a directory's only protection from a concurrently running
|
|
# job's eviction pass is "it happens to also be that job's own target dir",
|
|
# which is true for the job that owns it and false for everyone else. The
|
|
# marker is per-job (not just per-run) so two jobs sharing one cache key each
|
|
# hold an independent lock rather than one clobbering the other's.
|
|
#
|
|
# A lock is a timestamp file, not a real mutex: prune-cache.sh honours it only
|
|
# until STALE_LOCK_SECONDS, after which it is treated as abandoned by a job
|
|
# the runner killed before it reached its own release step. Honouring a lock
|
|
# forever would let one crashed job pin a directory permanently.
|
|
#
|
|
# `.ci-lock-<id>` IS A CROSS-REPO CONTRACT NAME with daniel/gitdan's
|
|
# `scripts/ci-cache-reclaim.sh`: that host-level arbiter reads this same
|
|
# marker (its `leftover_is_locked()`) to decide whether a leftover it is about
|
|
# to reclaim is still held open by a live job. `cache-lib.sh`'s
|
|
# `write_cache_lock()` writes the identical shape independently of this
|
|
# script. Rename or reshape this marker here without a matching change on
|
|
# gitdan's side and the arbiter's lock check silently stops matching — a live
|
|
# job's staging tree loses its liveness guard and becomes an ordinary reclaim
|
|
# candidate while still in use. See the "Scratch names in a cache root" section
|
|
# in README.md, and daniel/gitdan's `DEPENDED-UPON NAMES CONTRACT` block in
|
|
# `scripts/ci-cache-reclaim.sh`, for the full arrangement — this repo's half
|
|
# is: don't rename `.ci-lock-` without telling that script.
|
|
set -euo pipefail
|
|
|
|
MODE="${1:?usage: cache-lock.sh acquire|release <dir> <lock-id>}"
|
|
DIR="${2:?}"; ID="${3:?}"
|
|
|
|
case "$MODE" in
|
|
acquire)
|
|
mkdir -p "$DIR"
|
|
date +%s > "$DIR/.ci-lock-${ID}"
|
|
echo "lock: acquired .ci-lock-${ID} on $(basename "$DIR")"
|
|
;;
|
|
release)
|
|
rm -f "$DIR/.ci-lock-${ID}" 2>/dev/null || true
|
|
echo "lock: released .ci-lock-${ID} on $(basename "$DIR")"
|
|
;;
|
|
*)
|
|
echo "::error::cache-lock.sh: unknown mode '$MODE' (expected acquire or release)" >&2
|
|
exit 1
|
|
;;
|
|
esac
|