Skip to content
This repository was archived by the owner on May 14, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ def jellyfin_emby_server_connection(
status="disconnected",
version=""
)
app_state.increment_connection_failures()
logger.warning("Continuing with remaining servers...")

return servers
Expand Down Expand Up @@ -155,6 +156,7 @@ def generate_server_connections(env) -> list[Plex | Jellyfin | Emby]:
status="disconnected",
version=""
)
app_state.increment_connection_failures()
logger.warning("Continuing with remaining servers...")

if plex_username_str and plex_password_str and plex_servername_str:
Expand Down Expand Up @@ -208,6 +210,7 @@ def generate_server_connections(env) -> list[Plex | Jellyfin | Emby]:
status="disconnected",
version=""
)
app_state.increment_connection_failures()
logger.warning("Continuing with remaining servers...")

jellyfin_baseurl = get_env_value(env, "JELLYFIN_BASEURL", None)
Expand Down
31 changes: 30 additions & 1 deletion src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,13 +435,42 @@ def main() -> None:

# Check for manual sync requests from web dashboard
if web_dashboard_enabled:
# Sleep in small intervals to check for manual sync requests
# Sleep in small intervals to check for manual sync requests.
# If any servers failed to connect this cycle (e.g. they were
# still in startup maintenance after an Unraid reboot), retry
# connections every CONNECTION_RETRY_INTERVAL seconds and
# trigger an immediate sync if they all come back.
CONNECTION_RETRY_INTERVAL = 60
elapsed = 0
last_retry_at = 0
while elapsed < sleep_duration:
if app_state.manual_sync_requested:
logger.info("Web: Manual sync request detected, starting sync now")
app_state.clear_manual_sync_request()
break

if (
app_state.get_connection_failures() > 0
and (elapsed - last_retry_at) >= CONNECTION_RETRY_INTERVAL
):
last_retry_at = elapsed
prior_failures = app_state.get_connection_failures()
logger.info(
f"Retrying {prior_failures} failed server connection(s)..."
)
try:
generate_server_connections(env)
except Exception as e:
logger.error(f"Reconnect attempt failed: {e}")
if (
app_state.get_connection_failures() == 0
and prior_failures > 0
):
logger.info(
"All servers reconnected; triggering immediate sync"
)
app_state.request_manual_sync()

sleep(1)
elapsed += 1
else:
Expand Down
16 changes: 16 additions & 0 deletions src/web/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ def __init__(self):
# Server status
self.servers = {} # {server_name: {type, status, version}}

# Number of servers that failed to connect during the most recent
# connection cycle. Used by the main loop to decide whether to retry
# connections at a faster cadence (e.g. after Unraid reboot, when
# Plex/Jellyfin may still be in startup maintenance).
self.connection_failures = 0

# Statistics
self.total_items_synced = 0
self.total_users = 0
Expand Down Expand Up @@ -83,6 +89,16 @@ def reset_servers(self):
"""
with self._lock:
self.servers = {}
self.connection_failures = 0

def increment_connection_failures(self):
"""Record that a server failed to connect during the current cycle."""
with self._lock:
self.connection_failures += 1

def get_connection_failures(self) -> int:
with self._lock:
return self.connection_failures

def update_stats(self, items_synced: int = 0, users: int = 0):
"""Update sync statistics."""
Expand Down
Loading