fixed an error in transcode manager

This commit is contained in:
2026-04-11 09:01:15 -04:00
parent 70a58feee6
commit 7848b7c551
+80 -65
View File
@@ -7,7 +7,7 @@
# Run every 2-3 minutes via cron/User Scripts plugin. # Run every 2-3 minutes via cron/User Scripts plugin.
# #
# Logic: # Logic:
# Ramdisk not found → ensure symlink points to SSD, notify # Ramdisk not found → ensure symlink points to SSD, notify
# Usage < RAMDISK_LOW_GB → ensure symlink points to ramdisk # Usage < RAMDISK_LOW_GB → ensure symlink points to ramdisk
# Usage >= RAMDISK_WARN_GB → flip symlink to SSD (after checking SSD has space) # Usage >= RAMDISK_WARN_GB → flip symlink to SSD (after checking SSD has space)
# Only notifies on STATE CHANGE — silent when nothing changes # Only notifies on STATE CHANGE — silent when nothing changes
@@ -47,14 +47,14 @@ success "Running as root"
if [[ "$SHOW_STATUS" == true ]]; then if [[ "$SHOW_STATUS" == true ]]; then
echo "" echo ""
echo "━━━━━ $ICON_SUMMARY STATUS ━━━━━" echo "━━━━━ $ICON_SUMMARY STATUS ━━━━━"
echo "$ICON_RAM Ramdisk path: $RAMDISK_PATH" echo "$ICON_RAM Ramdisk path: $RAMDISK_PATH"
echo "$ICON_RAM Warn at: ${RAMDISK_WARN_GB}GB" echo "$ICON_RAM Warn at: ${RAMDISK_WARN_GB}GB"
echo "$ICON_RAM Back to RAM at: ${RAMDISK_LOW_GB}GB" echo "$ICON_RAM Back to RAM at: ${RAMDISK_LOW_GB}GB"
echo "$ICON_DISK SSD fallback: $TRANSCODE_SSD" echo "$ICON_DISK SSD fallback: $TRANSCODE_SSD"
echo "$ICON_DISK SSD min free: ${RAMDISK_SSD_MIN_GB}GB" echo "$ICON_DISK SSD min free: ${RAMDISK_SSD_MIN_GB}GB"
echo "$ICON_LINK Symlink: $TRANSCODE_LINK" echo "$ICON_LINK Symlink: $TRANSCODE_LINK"
echo "$ICON_NOTIFY Flip warn: $TRANSCODE_FLIP_WARN per hour" echo "$ICON_NOTIFY Flip warn: $TRANSCODE_FLIP_WARN per hour"
echo "$ICON_GEAR Dry Run: $DRY_RUN" echo "$ICON_GEAR Dry Run: $DRY_RUN"
if [[ -f "$STATE_FILE" ]]; then if [[ -f "$STATE_FILE" ]]; then
echo "" echo ""
@@ -87,9 +87,9 @@ set_state() {
fi fi
} }
# Initialise state file if missing — ramdisk_setup.sh creates it but just in case
init_state() { init_state() {
if [[ ! -f "$STATE_FILE" ]]; then if [[ ! -f "$STATE_FILE" ]]; then
local NOW
NOW=$(date +%s) NOW=$(date +%s)
cat > "$STATE_FILE" <<EOF cat > "$STATE_FILE" <<EOF
current_target=$RAMDISK_PATH current_target=$RAMDISK_PATH
@@ -103,9 +103,6 @@ EOF
# ----------------------------------------------------------------------------------------------- # -----------------------------------------------------------------------------------------------
# FLIP TRACKING # FLIP TRACKING
# Tracks how many times symlink has flipped in the current hour window.
# Resets counter when hour window rolls over.
# Notifies if flip count exceeds TRANSCODE_FLIP_WARN.
# ----------------------------------------------------------------------------------------------- # -----------------------------------------------------------------------------------------------
track_flip() { track_flip() {
local NOW local NOW
@@ -117,7 +114,6 @@ track_flip() {
[[ -z "$FLIP_COUNT" ]] && FLIP_COUNT=0 [[ -z "$FLIP_COUNT" ]] && FLIP_COUNT=0
[[ -z "$HOUR_START" ]] && HOUR_START=$NOW [[ -z "$HOUR_START" ]] && HOUR_START=$NOW
# Reset counter if hour window has passed
if (( NOW - HOUR_START >= 3600 )); then if (( NOW - HOUR_START >= 3600 )); then
FLIP_COUNT=0 FLIP_COUNT=0
set_state "flip_hour_start" "$NOW" set_state "flip_hour_start" "$NOW"
@@ -137,40 +133,46 @@ track_flip() {
# ----------------------------------------------------------------------------------------------- # -----------------------------------------------------------------------------------------------
# SYMLINK MANAGEMENT # SYMLINK MANAGEMENT
# Changes the transcode symlink target. # Sets the symlink to the desired target.
# Only flips if current target differs from desired target. # Only flips if current target differs — tracks flip for frequency monitoring.
# Tracks flip for frequency monitoring. # Force mode skips the state check and always sets the symlink (used for recovery).
# ----------------------------------------------------------------------------------------------- # -----------------------------------------------------------------------------------------------
set_symlink() { set_symlink() {
local target="$1" local target="$1" force="${2:-false}"
local current_target local current_target
current_target=$(get_state "current_target") current_target=$(get_state "current_target")
if [[ "$current_target" == "$target" ]]; then if [[ "$force" == false && "$current_target" == "$target" ]]; then
log "Symlink already points to $target — no change" log "Symlink already points to $target — no change"
return 0 return 0
fi fi
if [[ "$DRY_RUN" == true ]]; then if [[ "$DRY_RUN" == true ]]; then
warn "DRY RUN — would flip symlink: $TRANSCODE_LINK$target" warn "DRY RUN — would set symlink: $TRANSCODE_LINK$target"
return 0 return 0
fi fi
info "$ICON_LINK Flipping symlink: $TRANSCODE_LINK$target" info "$ICON_LINK Setting symlink: $TRANSCODE_LINK$target"
# Ensure parent directory exists
mkdir -p "$(dirname "$TRANSCODE_LINK")"
if ln -sfn "$target" "$TRANSCODE_LINK"; then if ln -sfn "$target" "$TRANSCODE_LINK"; then
success "$ICON_LINK Symlink updated$target" success "$ICON_LINK Symlink set$target"
set_state "current_target" "$target" set_state "current_target" "$target"
track_flip
if [[ "$target" == "$RAMDISK_PATH" ]]; then # Only track flip and notify if this was a real direction change
notify "Transcode symlink flipped to RAMDISK on $(hostname) — ramdisk has space" "Transcode Manager" "normal" if [[ "$current_target" != "$target" ]]; then
else track_flip
notify "Transcode symlink flipped to SSD on $(hostname) — ramdisk usage high" "Transcode Manager" "warning" if [[ "$target" == "$RAMDISK_PATH" ]]; then
notify "Transcode symlink flipped to RAMDISK on $(hostname) — ramdisk has space" "Transcode Manager" "normal"
else
notify "Transcode symlink flipped to SSD on $(hostname) — ramdisk usage high" "Transcode Manager" "warning"
fi
fi fi
else else
error "Failed to update symlink" error "Failed to set symlink: $TRANSCODE_LINK$target"
notify "Transcode symlink flip failed on $(hostname)" "Transcode Manager" "warning" notify "Transcode symlink failed to set on $(hostname)" "Transcode Manager" "warning"
return 1 return 1
fi fi
} }
@@ -187,29 +189,36 @@ START=$(date +%s)
# ----------------------------------------------------------------------------------------------- # -----------------------------------------------------------------------------------------------
# Symlink integrity check # Symlink integrity check
# If symlink is missing or target doesn't exist — force correct it immediately
# ----------------------------------------------------------------------------------------------- # -----------------------------------------------------------------------------------------------
info "$ICON_LINK Checking symlink integrity..." info "$ICON_LINK Checking symlink integrity..."
if [[ ! -L "$TRANSCODE_LINK" ]]; then SYMLINK_OK=true
error "$ICON_LINK Symlink missing: $TRANSCODE_LINK"
notify "Transcode symlink missing on $(hostname) — attempting recovery" "Transcode Manager" "warning"
# Attempt recovery — point at whichever location exists if [[ ! -L "$TRANSCODE_LINK" ]]; then
if mountpoint -q "$RAMDISK_PATH" 2>/dev/null; then error "$ICON_LINK Symlink missing: $TRANSCODE_LINK — recovering"
ln -sfn "$RAMDISK_PATH" "$TRANSCODE_LINK" && success "Symlink recovered → ramdisk" SYMLINK_OK=false
else
LINK_TARGET=$(readlink "$TRANSCODE_LINK" 2>/dev/null)
if [[ ! -d "$LINK_TARGET" ]]; then
error "$ICON_LINK Symlink target does not exist: $LINK_TARGET — recovering"
SYMLINK_OK=false
else else
ln -sfn "$TRANSCODE_SSD" "$TRANSCODE_LINK" && success "Symlink recovered → SSD" info "$ICON_LINK Symlink valid: $TRANSCODE_LINK$LINK_TARGET"
fi fi
fi fi
LINK_TARGET=$(readlink "$TRANSCODE_LINK" 2>/dev/null) # Force recovery — point at ramdisk if mounted, SSD otherwise
if [[ ! -d "$LINK_TARGET" ]]; then if [[ "$SYMLINK_OK" == false ]]; then
error "$ICON_LINK Symlink target does not exist: $LINK_TARGET" if mountpoint -q "$RAMDISK_PATH" 2>/dev/null; then
notify "Transcode symlink target missing on $(hostname): $LINK_TARGET" "Transcode Manager" "warning" warn "Recovering symlink → ramdisk"
set_symlink "$RAMDISK_PATH" force
else
warn "Ramdisk not mounted — recovering symlink → SSD"
set_symlink "$TRANSCODE_SSD" force
fi
fi fi
info "$ICON_LINK Current target: $LINK_TARGET"
# ----------------------------------------------------------------------------------------------- # -----------------------------------------------------------------------------------------------
# Ramdisk mount check # Ramdisk mount check
# ----------------------------------------------------------------------------------------------- # -----------------------------------------------------------------------------------------------
@@ -224,7 +233,7 @@ if ! mountpoint -q "$RAMDISK_PATH" 2>/dev/null; then
fi fi
if [[ "$RAMDISK_MOUNTED" == true ]]; then if [[ "$RAMDISK_MOUNTED" == true ]]; then
# Verify ramdisk size is correct # Verify ramdisk size matches expected
MOUNTED_SIZE=$(df -BG "$RAMDISK_PATH" | awk 'NR==2 {print $2}' | tr -d 'G') MOUNTED_SIZE=$(df -BG "$RAMDISK_PATH" | awk 'NR==2 {print $2}' | tr -d 'G')
EXPECTED_SIZE=$(echo "$RAMDISK_SIZE" | tr -d 'G') EXPECTED_SIZE=$(echo "$RAMDISK_SIZE" | tr -d 'G')
if [[ "$MOUNTED_SIZE" != "$EXPECTED_SIZE" ]]; then if [[ "$MOUNTED_SIZE" != "$EXPECTED_SIZE" ]]; then
@@ -233,15 +242,17 @@ if [[ "$RAMDISK_MOUNTED" == true ]]; then
success "$ICON_RAM Ramdisk mounted and correct size (${RAMDISK_SIZE})" success "$ICON_RAM Ramdisk mounted and correct size (${RAMDISK_SIZE})"
fi fi
# Get current usage # Get current usage in KB — use raw bytes to avoid scientific notation issues
RAMDISK_USED_KB=$(df "$RAMDISK_PATH" | awk 'NR==2 {print $3}') RAMDISK_USED_KB=$(df "$RAMDISK_PATH" --output=used | tail -1 | tr -d ' ')
RAMDISK_AVAIL_KB=$(df "$RAMDISK_PATH" | awk 'NR==2 {print $4}') RAMDISK_AVAIL_KB=$(df "$RAMDISK_PATH" --output=avail | tail -1 | tr -d ' ')
RAMDISK_USED_GB=$(awk "BEGIN {printf \"%.1f\", $RAMDISK_USED_KB / 1024 / 1024}")
RAMDISK_AVAIL_GB=$(awk "BEGIN {printf \"%.1f\", $RAMDISK_AVAIL_KB / 1024 / 1024}") # Convert to GB for display using awk — avoids bash integer/float issues
RAMDISK_USED_GB=$(awk "BEGIN {printf \"%.2f\", $RAMDISK_USED_KB / 1048576}")
RAMDISK_AVAIL_GB=$(awk "BEGIN {printf \"%.2f\", $RAMDISK_AVAIL_KB / 1048576}")
info "$ICON_RAM Ramdisk usage: ${RAMDISK_USED_GB}GB used / ${RAMDISK_AVAIL_GB}GB available" info "$ICON_RAM Ramdisk usage: ${RAMDISK_USED_GB}GB used / ${RAMDISK_AVAIL_GB}GB available"
# Count sessions in ramdisk and SSD # File counts and sizes
RAMDISK_FILES=$(find "$RAMDISK_PATH" -type f 2>/dev/null | wc -l) RAMDISK_FILES=$(find "$RAMDISK_PATH" -type f 2>/dev/null | wc -l)
SSD_FILES=$(find "$TRANSCODE_SSD" -type f 2>/dev/null | wc -l) SSD_FILES=$(find "$TRANSCODE_SSD" -type f 2>/dev/null | wc -l)
RAMDISK_SIZE_HUMAN=$(du -sh "$RAMDISK_PATH" 2>/dev/null | cut -f1) RAMDISK_SIZE_HUMAN=$(du -sh "$RAMDISK_PATH" 2>/dev/null | cut -f1)
@@ -251,19 +262,19 @@ if [[ "$RAMDISK_MOUNTED" == true ]]; then
info "$ICON_DISK SSD files: $SSD_FILES ($SSD_SIZE_HUMAN)" info "$ICON_DISK SSD files: $SSD_FILES ($SSD_SIZE_HUMAN)"
# ----------------------------------------------------------------------------------------------- # -----------------------------------------------------------------------------------------------
# Symlink direction decision # Symlink direction decision — all comparisons via awk to handle float thresholds
# ----------------------------------------------------------------------------------------------- # -----------------------------------------------------------------------------------------------
WARN_THRESHOLD=$(awk "BEGIN {print $RAMDISK_WARN_GB * 1024 * 1024}") WARN_EXCEEDED=$(awk "BEGIN {print ($RAMDISK_USED_GB >= $RAMDISK_WARN_GB) ? 1 : 0}")
LOW_THRESHOLD=$(awk "BEGIN {print $RAMDISK_LOW_GB * 1024 * 1024}") LOW_RECOVERED=$(awk "BEGIN {print ($RAMDISK_USED_GB < $RAMDISK_LOW_GB) ? 1 : 0}")
if (( RAMDISK_USED_KB >= WARN_THRESHOLD )); then if [[ "$WARN_EXCEEDED" == "1" ]]; then
# Ramdisk is getting full — check SSD has space before flipping # Ramdisk is getting full — check SSD has enough space before flipping
info "$ICON_DISK Checking SSD fallback space..." info "$ICON_DISK Checking SSD fallback space..."
SSD_AVAIL_KB=$(df "$TRANSCODE_SSD" | awk 'NR==2 {print $4}') SSD_AVAIL_KB=$(df "$TRANSCODE_SSD" --output=avail | tail -1 | tr -d ' ')
SSD_AVAIL_GB=$(awk "BEGIN {printf \"%.1f\", $SSD_AVAIL_KB / 1024 / 1024}") SSD_AVAIL_GB=$(awk "BEGIN {printf \"%.2f\", $SSD_AVAIL_KB / 1048576}")
SSD_MIN_KB=$(awk "BEGIN {print $RAMDISK_SSD_MIN_GB * 1024 * 1024}") SSD_SUFFICIENT=$(awk "BEGIN {print ($SSD_AVAIL_GB >= $RAMDISK_SSD_MIN_GB) ? 1 : 0}")
if (( SSD_AVAIL_KB < SSD_MIN_KB )); then if [[ "$SSD_SUFFICIENT" == "0" ]]; then
error "$ICON_DISK SSD fallback only has ${SSD_AVAIL_GB}GB free — minimum is ${RAMDISK_SSD_MIN_GB}GB" error "$ICON_DISK SSD fallback only has ${SSD_AVAIL_GB}GB free — minimum is ${RAMDISK_SSD_MIN_GB}GB"
notify "Transcode SSD fallback critically low on $(hostname)${SSD_AVAIL_GB}GB free" "Transcode Manager" "warning" notify "Transcode SSD fallback critically low on $(hostname)${SSD_AVAIL_GB}GB free" "Transcode Manager" "warning"
else else
@@ -271,15 +282,15 @@ if [[ "$RAMDISK_MOUNTED" == true ]]; then
set_symlink "$TRANSCODE_SSD" set_symlink "$TRANSCODE_SSD"
fi fi
elif (( RAMDISK_USED_KB < LOW_THRESHOLD )); then elif [[ "$LOW_RECOVERED" == "1" ]]; then
# Ramdisk has recovered — flip back # Ramdisk has recovered — flip back
set_symlink "$RAMDISK_PATH" set_symlink "$RAMDISK_PATH"
else else
# In hysteresis gap — hold current state # In hysteresis gap — hold current state
CURRENT=$(get_state "current_target") CURRENT=$(get_state "current_target")
log "Usage ${RAMDISK_USED_GB}GB in hysteresis gap (${RAMDISK_LOW_GB}-${RAMDISK_WARN_GB}GB) — holding current target: $CURRENT" log "Usage ${RAMDISK_USED_GB}GB in hysteresis gap (${RAMDISK_LOW_GB}${RAMDISK_WARN_GB}GB) — holding: $CURRENT"
info "$ICON_RAM Usage in hysteresis gap — holding current symlink target" info "$ICON_RAM Usage in hysteresis gap — holding current symlink"
fi fi
fi fi
@@ -290,9 +301,13 @@ END=$(date +%s)
# ----------------------------------------------------------------------------------------------- # -----------------------------------------------------------------------------------------------
echo "" echo ""
echo "━━━━━ $ICON_SUMMARY TRANSCODE MANAGER SUMMARY ━━━━━" echo "━━━━━ $ICON_SUMMARY TRANSCODE MANAGER SUMMARY ━━━━━"
echo "$ICON_RAM Ramdisk: $([[ "$RAMDISK_MOUNTED" == true ]] && echo "${RAMDISK_USED_GB}GB used" || echo "NOT MOUNTED")" if [[ "$RAMDISK_MOUNTED" == true ]]; then
echo "$ICON_LINK Symlink: $TRANSCODE_LINK$(readlink "$TRANSCODE_LINK" 2>/dev/null || echo "BROKEN")" echo "$ICON_RAM Ramdisk: ${RAMDISK_USED_GB}GB used / ${RAMDISK_AVAIL_GB}GB available"
echo "$ICON_LINK Flip count: $(get_state "flip_count_hour") this hour (warn at $TRANSCODE_FLIP_WARN)" else
echo "$ICON_TIME Duration: $(format_duration $((END - START)))" echo "$ICON_RAM Ramdisk: NOT MOUNTED — using SSD"
echo "$ICON_DONE Status: $ICON_SUCCESS DONE" fi
echo "$ICON_LINK Symlink: $TRANSCODE_LINK$(readlink "$TRANSCODE_LINK" 2>/dev/null || echo "BROKEN")"
echo "$ICON_LINK Flips: $(get_state "flip_count_hour") this hour (warn at $TRANSCODE_FLIP_WARN)"
echo "$ICON_TIME Duration: $(format_duration $((END - START)))"
echo "$ICON_DONE Status: $ICON_SUCCESS DONE"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"