Add OPERATIONAL SAFEGUARDS headers, skip prefill during active rescans
arr_full_rescan.sh, arr_cache_prefill.sh, and arr_rescan_monitor.sh were missing the standard SAFEGUARDS header section other Arrs_Stack/Tools scripts have. Also: arr_cache_prefill.sh now checks for an active rescan before fetching, instead of doing a live fetch that arr_cache_write() would just refuse to persist anyway -- avoids wasted API calls every 30min during a long rescan. arr_rescan_monitor.sh was also missing an actual root check despite writing cache files; added it to match convention rather than just document a safeguard that wasn't there.
This commit is contained in:
@@ -6,11 +6,18 @@
|
|||||||
# PURPOSE
|
# PURPOSE
|
||||||
# ─────────────────────────────────────────────────────────────────────────────
|
# ─────────────────────────────────────────────────────────────────────────────
|
||||||
# Populates the shared tracked-data cache (see arr_get_tracked_data() in common.sh) for
|
# Populates the shared tracked-data cache (see arr_get_tracked_data() in common.sh) for
|
||||||
# Lidarr, Sonarr, and Radarr once at array start, before any other script needs it. Without
|
# Lidarr, Sonarr, and Radarr. Without this, each arr's cache stays cold until whichever
|
||||||
# this, each arr's cache stays cold from boot until whichever script happens to touch that
|
# script happens to touch that arr first writes through — which could be hours, depending
|
||||||
# arr first writes through — which could be hours, depending on the daily schedule. One-shot:
|
# on the daily schedule. Originally Lidarr-only (lidarr_cache_prefill.sh, 2026-07-16),
|
||||||
# runs and exits. Originally Lidarr-only (lidarr_cache_prefill.sh, 2026-07-16), generalized
|
# generalized the same day to cover all three arrs once the cache mechanism itself was
|
||||||
# the same day to cover all three arrs once the cache mechanism itself was generalized.
|
# generalized.
|
||||||
|
#
|
||||||
|
# Runs on two schedules (2026-07-17): once at array start (closes the cold-boot gap, 10min
|
||||||
|
# wait ceiling for slow-starting containers) and again every 30min via
|
||||||
|
# CRITICAL_MAINTENANCE_SCRIPTS with a 1min wait ceiling (ARR_PREFILL_WAIT_MINUTES=1 override)
|
||||||
|
# — a live fetch+write takes seconds, so there's no reason to tolerate the boot-time wait on
|
||||||
|
# a recurring job. This is what keeps the cache-first consumers' data reliably under 30min
|
||||||
|
# old instead of only refreshing whenever some other script happens to write through.
|
||||||
#
|
#
|
||||||
# ==============================================================================================
|
# ==============================================================================================
|
||||||
# OPERATIONAL MODEL
|
# OPERATIONAL MODEL
|
||||||
@@ -23,6 +30,22 @@
|
|||||||
# An arr not configured on this host (e.g. Lidarr is HOST1-only) is skipped cleanly.
|
# An arr not configured on this host (e.g. Lidarr is HOST1-only) is skipped cleanly.
|
||||||
#
|
#
|
||||||
# ==============================================================================================
|
# ==============================================================================================
|
||||||
|
# OPERATIONAL SAFEGUARDS
|
||||||
|
# ==============================================================================================
|
||||||
|
#
|
||||||
|
# Root required — chown-free here, but matches convention across Arrs_Stack/
|
||||||
|
# jq required — skips the whole run cleanly (not fatal) if jq is missing
|
||||||
|
# acquire_lock — prevents two invocations of this script overlapping (default strict
|
||||||
|
# mode) — matters if the boot-time run is still waiting on a slow
|
||||||
|
# container when the first 30min critical-tier tick fires
|
||||||
|
# Reachability retry — tolerates a slow-starting container up to ARR_PREFILL_WAIT_MINUTES;
|
||||||
|
# never fatal if one never comes up, that arr's cache just stays cold
|
||||||
|
# Active-rescan check — skips an arr this cycle if a rescan-type command is running, instead
|
||||||
|
# of a live fetch arr_cache_write() would refuse to persist anyway
|
||||||
|
# (2026-07-17) — avoids wasted API calls during a long rescan
|
||||||
|
# Per-arr isolation — one arr failing or timing out never blocks or fails the others
|
||||||
|
#
|
||||||
|
# ==============================================================================================
|
||||||
# CONFIGURATION
|
# CONFIGURATION
|
||||||
# ==============================================================================================
|
# ==============================================================================================
|
||||||
#
|
#
|
||||||
@@ -33,7 +56,10 @@
|
|||||||
# All aliased by detect_hosts()
|
# All aliased by detect_hosts()
|
||||||
#
|
#
|
||||||
# master.conf
|
# master.conf
|
||||||
# ARR_PREFILL_WAIT_MINUTES — how long to retry reaching each arr before giving up on it (default 10)
|
# ARR_PREFILL_WAIT_MINUTES — how long to retry reaching each arr before giving up on it
|
||||||
|
# (default 10). The CRITICAL_MAINTENANCE_SCRIPTS entry overrides this to 1 via parse_args'
|
||||||
|
# VAR=VAL mechanism for the 30min recurring run — the 10min default is sized for cold boot,
|
||||||
|
# not a job that fires every half hour.
|
||||||
#
|
#
|
||||||
# ==============================================================================================
|
# ==============================================================================================
|
||||||
|
|
||||||
@@ -78,6 +104,17 @@ _prefill_one() {
|
|||||||
(( waited += 15 ))
|
(( waited += 15 ))
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# Skip cleanly if a rescan-type command is already active — arr_cache_write() below
|
||||||
|
# would refuse to persist a mid-rescan snapshot anyway (2026-07-17 guard), so fetching
|
||||||
|
# it live first would just be a wasted API call every time this fires during a long
|
||||||
|
# rescan. Matches the same check arr_full_rescan.sh and the cleanup scripts already do.
|
||||||
|
local active_cmd
|
||||||
|
active_cmd=$(arr_active_rescan_command "$arr_type" "$url" "$api_key" "$api_version")
|
||||||
|
if [[ -n "$active_cmd" ]]; then
|
||||||
|
info "${arr_type^} mid-rescan ($active_cmd) — skipping this cycle, cache stays as-is"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
local endpoint="${ARR_LIBRARY_ENDPOINT[$arr_type]:-}"
|
local endpoint="${ARR_LIBRARY_ENDPOINT[$arr_type]:-}"
|
||||||
if [[ -z "$endpoint" ]]; then
|
if [[ -z "$endpoint" ]]; then
|
||||||
warn "No library endpoint known for ${arr_type} — skipping"
|
warn "No library endpoint known for ${arr_type} — skipping"
|
||||||
|
|||||||
@@ -20,6 +20,24 @@
|
|||||||
# and running them concurrently would just contend for the same disk I/O for no benefit.
|
# and running them concurrently would just contend for the same disk I/O for no benefit.
|
||||||
#
|
#
|
||||||
# ==============================================================================================
|
# ==============================================================================================
|
||||||
|
# OPERATIONAL SAFEGUARDS
|
||||||
|
# ==============================================================================================
|
||||||
|
#
|
||||||
|
# Root required — required for consistency across Arrs_Stack/, no direct fs writes here
|
||||||
|
# acquire_lock "wait" — waits for a prior run to finish rather than skipping or colliding;
|
||||||
|
# a full-library rescan across three arrs can run long, worth queuing
|
||||||
|
# behind rather than silently no-op'ing
|
||||||
|
# Reachability check — check_api before touching an arr; unreachable → skip that arr only
|
||||||
|
# Active-rescan check — skips triggering a NEW rescan if one's already active on that arr
|
||||||
|
# (manual trigger, another script) — never stacks a duplicate scan,
|
||||||
|
# see Tools/arr_rescan_monitor.sh for catching up that arr's cache
|
||||||
|
# once the pre-existing scan finishes instead of waiting for next week
|
||||||
|
# Sequential only — never runs two arrs' rescans in parallel; each is a heavy full-disk
|
||||||
|
# walk and concurrent walks would just contend for the same disk I/O
|
||||||
|
# Per-arr isolation — one arr failing, timing out, or being skipped never blocks the others
|
||||||
|
# --dry-run mode — reports which arrs would be rescanned, triggers nothing
|
||||||
|
#
|
||||||
|
# ==============================================================================================
|
||||||
# CONFIGURATION
|
# CONFIGURATION
|
||||||
# ==============================================================================================
|
# ==============================================================================================
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -19,6 +19,19 @@
|
|||||||
# this for scans it triggers itself; this tool covers everything else.
|
# this for scans it triggers itself; this tool covers everything else.
|
||||||
#
|
#
|
||||||
# ==============================================================================================
|
# ==============================================================================================
|
||||||
|
# OPERATIONAL SAFEGUARDS
|
||||||
|
# ==============================================================================================
|
||||||
|
#
|
||||||
|
# Root required — matches convention across Arrs_Stack/Tools/, writes cache files
|
||||||
|
# Arg validation — arr_type must be lidarr/sonarr/radarr, usage error otherwise
|
||||||
|
# Timeout, never waits forever — default 2h ceiling, override via second positional arg;
|
||||||
|
# on timeout, cache is left untouched rather than acted on stale
|
||||||
|
# --status mode — read-only, shows active rescan + cache age, waits/writes nothing
|
||||||
|
# --dry-run mode — shows what would be waited on, waits/writes nothing
|
||||||
|
# Triggers nothing — never starts a rescan itself, only watches one already running;
|
||||||
|
# use arr_full_rescan.sh or the arr's own UI/API to start one
|
||||||
|
#
|
||||||
|
# ==============================================================================================
|
||||||
# RUNTIME MODES
|
# RUNTIME MODES
|
||||||
# ==============================================================================================
|
# ==============================================================================================
|
||||||
#
|
#
|
||||||
@@ -40,6 +53,12 @@
|
|||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
source "$SCRIPT_DIR/../load_config.sh"
|
source "$SCRIPT_DIR/../load_config.sh"
|
||||||
parse_args "$@"
|
parse_args "$@"
|
||||||
|
|
||||||
|
if [[ "$EUID" -ne 0 ]]; then
|
||||||
|
error "Must be run as root"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
detect_hosts
|
detect_hosts
|
||||||
|
|
||||||
ARR_TYPE="${PARSED_ARGS[0]:-}"
|
ARR_TYPE="${PARSED_ARGS[0]:-}"
|
||||||
|
|||||||
Reference in New Issue
Block a user