From c4d4d8160d0e3f746721787f998f2c3e080e150d Mon Sep 17 00:00:00 2001 From: Gmer4Lfe Date: Mon, 22 Jun 2026 23:14:36 -0400 Subject: [PATCH] Replace Emby dirty-sync workaround with play_state_sync in handback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Emby now runs continuously on both hosts — play_state_sync via API handles watch state reconciliation, making the 30-min dirty rsync redundant. Handback runs play_state_sync --wait before DNS cutover so users land on current state after a failover event. - Emby removed from FALLBACK_HOST1_TIER1 (always running) - Emby dirty sync removed from HOST1_CRITICAL_SYNC_SHARES - Emby writeback removed from FALLBACK_HOST1_WRITEBACK_TIER1 - play_state_sync gains --wait flag (uses lock wait mode for handback) - Tier 1 emby-fallback special case removed from handback writeback loop - play_state_sync --wait added as Step 7 in handback, before DNS cutover --- Fallback/fallback.sh | 23 ++++++++++++++++------- Media/play_state_sync.sh | 13 ++++++++++--- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/Fallback/fallback.sh b/Fallback/fallback.sh index 244f4d6..0cc4961 100755 --- a/Fallback/fallback.sh +++ b/Fallback/fallback.sh @@ -772,11 +772,7 @@ run_handback() { [[ -z "$job" ]] && continue log "Syncing: $job" if [[ "$DRY_RUN" == false ]]; then - if [[ "$(basename "$job")" == "Emby" ]]; then - bash "$SCRIPT_DIR/../Rsync/rsync.sh" "$job" --profile=emby-fallback - else - bash "$SCRIPT_DIR/../Rsync/rsync.sh" "$job" - fi + bash "$SCRIPT_DIR/../Rsync/rsync.sh" "$job" else warn "DRY RUN — would rsync: $job" fi @@ -797,7 +793,20 @@ run_handback() { [[ "$is_ddns" == false ]] && remote_start "$container" done - # ── Step 7: DNS Cutover — final step ──────────────────────────────────────────────────── + # ── Step 7: Play State Sync — before DNS cutover so users land on current state ────────── + echo "" + echo "━━━ $ICON_SYNC Play State Sync ━━━" + if [[ "$DRY_RUN" == false ]]; then + if bash "$SCRIPT_DIR/../Media/play_state_sync.sh" --wait; then + log "Play state synced — $REMOTE_SERVER_NAME watch state reconciled ✅" + else + warn "play_state_sync failed — users may see stale watch state until next sync cycle" + fi + else + warn "DRY RUN — would run play_state_sync --wait" + fi + + # ── Step 8: DNS Cutover — final step ──────────────────────────────────────────────────── # DNS cuts over ONLY after Tier 1 containers confirmed up echo "" echo "━━━ $ICON_NET DNS Cutover ━━━" @@ -807,7 +816,7 @@ run_handback() { done warn "$ICON_NET Remote DDNS started — DNS now points at $REMOTE_SERVER_NAME" - # ── Step 8: Return to NORMAL ───────────────────────────────────────────────────────────── + # ── Step 9: Return to NORMAL ───────────────────────────────────────────────────────────── echo "" state_set state "NORMAL" state_set fallback_start "0" diff --git a/Media/play_state_sync.sh b/Media/play_state_sync.sh index 71e811b..40634b7 100755 --- a/Media/play_state_sync.sh +++ b/Media/play_state_sync.sh @@ -73,11 +73,18 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/../load_config.sh" -# ── Handle --full before parse_args ─────────────────────────────────────────── +# ── Handle --full and --wait before parse_args ──────────────────────────────── FULL_SYNC=false +LOCK_MODE="strict" _FILTERED=() for _a in "$@"; do - [[ "$_a" == "--full" ]] && FULL_SYNC=true || _FILTERED+=("$_a") + if [[ "$_a" == "--full" ]]; then + FULL_SYNC=true + elif [[ "$_a" == "--wait" ]]; then + LOCK_MODE="wait" + else + _FILTERED+=("$_a") + fi done parse_args "${_FILTERED[@]}" @@ -93,7 +100,7 @@ log "$ICON_GEAR Config: days=${SYNC_DAYS} types=${SYNC_TYPES} remote=${PLAY_SYNC command -v jq >/dev/null 2>&1 || { error "jq is required but not installed"; exit 1; } -acquire_lock +acquire_lock "$LOCK_MODE" # ── Build server list across ALL hosts ──────────────────────────────────────── # All HOST*_TRANSCODE_SERVERS arrays are loaded into env by load_config.sh.