breakglass-sync: per-owner soft budget (OWNER_BUDGET_SEC, default 2h)
Once an owner consumes more than OWNER_BUDGET_SEC seconds, the script stops starting new repos for that owner and moves on to the next. The in-flight repo finishes naturally — we never kill mid-push. ONLY_REPO mode bypasses the budget (single-repo runs are intentional). Surfaced via a new OWNERS_DEFERRED counter in the summary line + an OWNER_BUDGET_EXCEEDED audit event per owner. Originally added after signalapp was starved by openclaw repeatedly consuming the whole window. With 12 owners and a 16h sync timeout, 2h/owner gives ample headroom while preventing any single owner from monopolising the run. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c0a66add46
commit
46c6e5a9c3
@ -58,6 +58,12 @@ SYNC_RELEASES="${SYNC_RELEASES:-true}"
|
|||||||
REVERSE_SYNC_REPOS="${REVERSE_SYNC_REPOS:-}"
|
REVERSE_SYNC_REPOS="${REVERSE_SYNC_REPOS:-}"
|
||||||
GITHUB_PUSH_TOKEN="${GITHUB_PUSH_TOKEN:-}"
|
GITHUB_PUSH_TOKEN="${GITHUB_PUSH_TOKEN:-}"
|
||||||
GITHUB_PUSH_OWNER="${GITHUB_PUSH_OWNER:-}"
|
GITHUB_PUSH_OWNER="${GITHUB_PUSH_OWNER:-}"
|
||||||
|
# Per-owner soft budget. Once exceeded, the script stops starting new repos
|
||||||
|
# for that owner and moves on to the next. The in-flight repo (if any)
|
||||||
|
# finishes naturally — we never kill mid-push. Set to 0 to disable.
|
||||||
|
# Default 7200s (2h). Originally added 2026-05-28 after signalapp was
|
||||||
|
# starved by openclaw repeatedly consuming the whole window.
|
||||||
|
OWNER_BUDGET_SEC="${OWNER_BUDGET_SEC:-7200}"
|
||||||
|
|
||||||
mkdir -p "$MIRROR_ROOT" "$RELEASE_ROOT" "$LOG_DIR" "$AUDIT_DIR"
|
mkdir -p "$MIRROR_ROOT" "$RELEASE_ROOT" "$LOG_DIR" "$AUDIT_DIR"
|
||||||
|
|
||||||
@ -68,6 +74,7 @@ ERRORS=0
|
|||||||
SYNCED=0
|
SYNCED=0
|
||||||
SKIPPED=0
|
SKIPPED=0
|
||||||
PROTECTED=0
|
PROTECTED=0
|
||||||
|
OWNERS_DEFERRED=0
|
||||||
|
|
||||||
# ── Helpers ──────────────────────────────────────────────
|
# ── Helpers ──────────────────────────────────────────────
|
||||||
|
|
||||||
@ -1092,9 +1099,24 @@ if [[ -z "$REVERSE_SYNC_ONLY" ]]; then
|
|||||||
repos=$(gh_list_repos "$gh_owner") || { (( ERRORS++ )) || true; continue; }
|
repos=$(gh_list_repos "$gh_owner") || { (( ERRORS++ )) || true; continue; }
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
owner_start=$(date +%s)
|
||||||
|
|
||||||
while IFS= read -r repo; do
|
while IFS= read -r repo; do
|
||||||
[[ -z "$repo" ]] && continue
|
[[ -z "$repo" ]] && continue
|
||||||
|
|
||||||
|
# Per-owner budget: stop starting new repos once exceeded.
|
||||||
|
# The in-flight repo finishes naturally; we just don't begin another.
|
||||||
|
# ONLY_REPO mode bypasses the budget (single-repo runs are intentional).
|
||||||
|
if [[ -z "$ONLY_REPO" ]] && (( OWNER_BUDGET_SEC > 0 )); then
|
||||||
|
owner_elapsed=$(( $(date +%s) - owner_start ))
|
||||||
|
if (( owner_elapsed > OWNER_BUDGET_SEC )); then
|
||||||
|
warn "owner $gh_owner exceeded budget (${owner_elapsed}s > ${OWNER_BUDGET_SEC}s) — deferring remaining repos to next run"
|
||||||
|
audit "OWNER_BUDGET_EXCEEDED owner=$gh_owner elapsed=${owner_elapsed}s budget=${OWNER_BUDGET_SEC}s"
|
||||||
|
(( OWNERS_DEFERRED++ )) || true
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ -z "$ONLY_REPO" ]]; then
|
if [[ -z "$ONLY_REPO" ]]; then
|
||||||
if ! matches_glob "$repo" "${include_glob:-*}"; then
|
if ! matches_glob "$repo" "${include_glob:-*}"; then
|
||||||
(( SKIPPED++ )) || true; continue
|
(( SKIPPED++ )) || true; continue
|
||||||
@ -1126,7 +1148,7 @@ fi
|
|||||||
|
|
||||||
DURATION=$(( $(date +%s) - $(date -d "$TIMESTAMP" +%s 2>/dev/null || date -u -d "${TIMESTAMP:0:8} ${TIMESTAMP:9:2}:${TIMESTAMP:11:2}:${TIMESTAMP:13:2}" +%s 2>/dev/null || echo 0) ))
|
DURATION=$(( $(date +%s) - $(date -d "$TIMESTAMP" +%s 2>/dev/null || date -u -d "${TIMESTAMP:0:8} ${TIMESTAMP:9:2}:${TIMESTAMP:11:2}:${TIMESTAMP:13:2}" +%s 2>/dev/null || echo 0) ))
|
||||||
DURATION_MIN=$(( DURATION / 60 ))
|
DURATION_MIN=$(( DURATION / 60 ))
|
||||||
SUMMARY="Breakglass sync: ${SYNCED} synced, ${SKIPPED} skipped, ${PROTECTED} wipe-protected, ${ERRORS} errors (${DURATION_MIN}m)"
|
SUMMARY="Breakglass sync: ${SYNCED} synced, ${SKIPPED} skipped, ${PROTECTED} wipe-protected, ${ERRORS} errors, ${OWNERS_DEFERRED} owners deferred (${DURATION_MIN}m)"
|
||||||
log ""
|
log ""
|
||||||
log "═══ $SUMMARY ═══"
|
log "═══ $SUMMARY ═══"
|
||||||
audit "SESSION_END $SUMMARY"
|
audit "SESSION_END $SUMMARY"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user