Compare commits

...
2 Commits
Author SHA1 Message Date
Eric WagonerandClaude Opus 5.5 f0d7237c2b The rollup and the backup check in once, when they end, with the run's duration
A start and a finish sent seconds apart can reach Sentry in either order,
and a start that lands second is never closed, so a fast rollup was
reported as a timeout on nights it succeeded. Hnefatafl's monitor did so
nine nights in fifteen. One check-in at the end cannot race; a run that
hangs sends nothing and is marked missed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwFKMuQnPAEHJ5yA1q4orh
2026-10-10 17:44:43 -04:00
Eric WagonerandClaude Opus 5.5 567590464e hall-announce --clear leaves an empty notice rather than no file, so no page's check is a failed request
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-10-05 21:55:28 -04:00
3 changed files with 16 additions and 6 deletions

No files matched your search

+4 -2
View File
@@ -10,9 +10,11 @@
set -euo pipefail set -euo pipefail
FILE=/var/lib/hall/announcement.json FILE=/var/lib/hall/announcement.json
# No notice is an empty one, {}, never a missing file: a page's check for a missing file
# is a failed request, and the browser reports it in every visitor's console.
case "${1:-}" in case "${1:-}" in
--clear) rm -f "$FILE"; echo "cleared."; exit 0 ;; --clear) mkdir -p "$(dirname "$FILE")"; echo '{}' > "$FILE.tmp"; chmod 644 "$FILE.tmp"; mv "$FILE.tmp" "$FILE"; echo "cleared."; exit 0 ;;
--show) cat "$FILE" 2>/dev/null || echo "no announcement."; exit 0 ;; --show) if grep -q '"text"' "$FILE" 2>/dev/null; then cat "$FILE"; else echo "no announcement."; fi; exit 0 ;;
''|-*) sed -n '2,9p' "$0" | sed 's/^# \{0,1\}//'; exit 2 ;; ''|-*) sed -n '2,9p' "$0" | sed 's/^# \{0,1\}//'; exit 2 ;;
esac esac
+6 -2
View File
@@ -14,9 +14,14 @@ LOG="/var/log/__SLUG__/backup.log"
STAMP=$(date +%Y-%m-%d) STAMP=$(date +%Y-%m-%d)
mkdir -p "$(dirname "$LOG")" mkdir -p "$(dirname "$LOG")"
CRON_URL=$(cat /root/.__SLUG__-sentry-cron 2>/dev/null || true) CRON_URL=$(cat /root/.__SLUG__-sentry-cron 2>/dev/null || true)
# One check-in, when the run ends, carrying its duration: a start and a
# finish sent seconds apart can reach Sentry in either order, and a start
# that lands second is never closed. A run that never ends sends nothing,
# and Sentry marks the night missed.
START=$SECONDS
checkin() { checkin() {
[ -n "$CRON_URL" ] && curl -sf -o /dev/null -X POST -H "Content-Type: application/json" \ [ -n "$CRON_URL" ] && curl -sf -o /dev/null -X POST -H "Content-Type: application/json" \
-d "{\"status\":\"$1\",\"monitor_config\":{\"schedule\":{\"type\":\"crontab\",\"value\":\"$SCHEDULE\"},\"checkin_margin\":30,\"max_runtime\":10,\"timezone\":\"UTC\"}}" \ -d "{\"status\":\"$1\",\"duration\":$((SECONDS - START)),\"monitor_config\":{\"schedule\":{\"type\":\"crontab\",\"value\":\"$SCHEDULE\"},\"checkin_margin\":30,\"max_runtime\":10,\"timezone\":\"UTC\"}}" \
"$CRON_URL" || true "$CRON_URL" || true
} }
@@ -27,7 +32,6 @@ fi
{ {
echo "=== $(date -Is) backup start" echo "=== $(date -Is) backup start"
checkin in_progress
if rclone sync "$SRC" "spaces:$BUCKET/$PREFIX/current" --exclude 'rollup.jsonl' 2>&1 && if rclone sync "$SRC" "spaces:$BUCKET/$PREFIX/current" --exclude 'rollup.jsonl' 2>&1 &&
rclone copy "$SRC" "spaces:$BUCKET/$PREFIX/snapshots/$STAMP" 2>&1; then rclone copy "$SRC" "spaces:$BUCKET/$PREFIX/snapshots/$STAMP" 2>&1; then
checkin ok checkin ok
+6 -2
View File
@@ -16,13 +16,17 @@ DAY="${1:-$(date -u -d 'yesterday' +%Y-%m-%d)}"
SCHEDULE="12 0 * * *" SCHEDULE="12 0 * * *"
CRON_URL=$(cat /root/.__SLUG__-sentry-cron-rollup 2>/dev/null || true) CRON_URL=$(cat /root/.__SLUG__-sentry-cron-rollup 2>/dev/null || true)
# The check-in carries the schedule: Sentry keeps a monitor only once told its shape. # The check-in carries the schedule: Sentry keeps a monitor only once told its shape.
# One check-in, when the run ends, carrying its duration: a start and a
# finish sent seconds apart can reach Sentry in either order, and a start
# that lands second is never closed. A run that never ends sends nothing,
# and Sentry marks the night missed.
START=$SECONDS
checkin() { checkin() {
[ -n "$CRON_URL" ] && curl -sf -o /dev/null -X POST -H "Content-Type: application/json" \ [ -n "$CRON_URL" ] && curl -sf -o /dev/null -X POST -H "Content-Type: application/json" \
-d "{\"status\":\"$1\",\"monitor_config\":{\"schedule\":{\"type\":\"crontab\",\"value\":\"$SCHEDULE\"},\"checkin_margin\":30,\"max_runtime\":10,\"timezone\":\"UTC\"}}" \ -d "{\"status\":\"$1\",\"duration\":$((SECONDS - START)),\"monitor_config\":{\"schedule\":{\"type\":\"crontab\",\"value\":\"$SCHEDULE\"},\"checkin_margin\":30,\"max_runtime\":10,\"timezone\":\"UTC\"}}" \
"$CRON_URL" || true "$CRON_URL" || true
} }
mkdir -p "$(dirname "$LOG")" mkdir -p "$(dirname "$LOG")"
checkin in_progress
if python3 - "$DAY" "$OUT" <<'PY' >> "$LOG" 2>&1 if python3 - "$DAY" "$OUT" <<'PY' >> "$LOG" 2>&1
import datetime, glob, json, os, shutil, sys import datetime, glob, json, os, shutil, sys
sys.path.insert(0, "/usr/local/lib/__SLUG__") sys.path.insert(0, "/usr/local/lib/__SLUG__")