C1: Migrate status-check dispatch sites to engine
Two sites in web_server.py replaced:
- /status route's media-server connectivity check (4-way if/elif
for plex/jellyfin/navidrome/soulsync) → engine.is_connected()
- /api/playlists endpoint's server_connected check (3-way if/elif)
→ engine.is_connected()
Engine reads active_server config + dispatches to the right client
with internal connection caching preserved (the underlying clients
all cache is_connected() calls).
Engine constructor now accepts a pre-built clients={...} dict so
web_server.py wires the same instances as its existing per-client
globals — no double-init.
Suite still green. Per-server clients still accessible via
engine.client(name) for source-specific reaches.
This commit is contained in:
parent
6b54ca6598
commit
971d683ebd
2 changed files with 47 additions and 24 deletions
|
|
@ -45,6 +45,7 @@ class MediaServerEngine:
|
|||
self,
|
||||
registry: Optional[MediaServerRegistry] = None,
|
||||
active_server_resolver=None,
|
||||
clients: Optional[Dict[str, Any]] = None,
|
||||
) -> None:
|
||||
"""Initialize the engine.
|
||||
|
||||
|
|
@ -56,9 +57,29 @@ class MediaServerEngine:
|
|||
``config_manager.get_active_media_server``. Tests
|
||||
inject a custom resolver to switch active server
|
||||
without touching real config.
|
||||
clients: Pre-built {name: client_instance} dict. When
|
||||
provided, the engine wraps these instances directly
|
||||
instead of asking the registry to construct fresh
|
||||
ones. web_server.py uses this so the engine
|
||||
shares the same client objects as the
|
||||
pre-existing global variables (no double-init).
|
||||
"""
|
||||
self.registry = registry if registry is not None else build_default_registry()
|
||||
self.registry.initialize()
|
||||
|
||||
if clients is not None:
|
||||
# Wrap pre-built instances (production case from web_server.py
|
||||
# init). Skip registry.initialize() — we already have the
|
||||
# instances, just stash them in the registry's slots so
|
||||
# registry.get(name) works.
|
||||
for name, client in clients.items():
|
||||
self.registry._instances[name] = client
|
||||
# Mark any registered-but-not-supplied as failed init so
|
||||
# active_client() returns None for them.
|
||||
for name in self.registry._specs:
|
||||
if name not in self.registry._instances:
|
||||
self.registry._instances[name] = None
|
||||
else:
|
||||
self.registry.initialize()
|
||||
|
||||
if active_server_resolver is None:
|
||||
from config.settings import config_manager
|
||||
|
|
|
|||
|
|
@ -603,6 +603,23 @@ try:
|
|||
except Exception as e:
|
||||
logger.error(f" SoulSync library client failed to initialize: {e}")
|
||||
|
||||
# Build the MediaServerEngine on top of the per-client globals above.
|
||||
# Engine wraps the same instances — no double-init. Provides
|
||||
# ``engine.method()`` dispatch in place of the historic
|
||||
# ``if active_server == 'plex' / 'jellyfin' / ...`` chains.
|
||||
try:
|
||||
from core.media_server import MediaServerEngine
|
||||
media_server_engine = MediaServerEngine(clients={
|
||||
'plex': plex_client,
|
||||
'jellyfin': jellyfin_client,
|
||||
'navidrome': navidrome_client,
|
||||
'soulsync': soulsync_library_client,
|
||||
})
|
||||
logger.info(" Media server engine initialized")
|
||||
except Exception as e:
|
||||
logger.error(f" Media server engine failed to initialize: {e}")
|
||||
media_server_engine = None
|
||||
|
||||
try:
|
||||
soulseek_client = DownloadOrchestrator()
|
||||
logger.info(" Download orchestrator initialized")
|
||||
|
|
@ -3460,23 +3477,14 @@ def get_status():
|
|||
|
||||
metadata_status = get_metadata_status_snapshot(spotify_client=spotify_client)
|
||||
|
||||
# Test media server - use EXISTING instances (they have internal caching)
|
||||
# Media server clients already cache connection checks internally
|
||||
# Test media server — engine reads active_server config + dispatches
|
||||
# to the right client (with internal connection caching). Engine
|
||||
# returns False safely if the active client is None / not registered.
|
||||
if current_time - _status_cache_timestamps['media_server'] > STATUS_CACHE_TTL:
|
||||
media_server_start = time.time()
|
||||
media_server_status = False
|
||||
if active_server == "plex" and plex_client:
|
||||
# Use existing instance - has 30s internal connection cache
|
||||
media_server_status = plex_client.is_connected()
|
||||
elif active_server == "jellyfin" and jellyfin_client:
|
||||
# Use existing instance - has internal connection caching
|
||||
media_server_status = jellyfin_client.is_connected()
|
||||
elif active_server == "navidrome" and navidrome_client:
|
||||
# Use existing instance
|
||||
media_server_status = navidrome_client.is_connected()
|
||||
elif active_server == "soulsync":
|
||||
# Standalone mode — always connected if Transfer folder exists
|
||||
media_server_status = soulsync_library_client.is_connected() if soulsync_library_client else False
|
||||
media_server_status = (
|
||||
media_server_engine.is_connected() if media_server_engine else False
|
||||
)
|
||||
media_server_response_time = (time.time() - media_server_start) * 1000
|
||||
_status_cache['media_server'] = {
|
||||
'connected': media_server_status,
|
||||
|
|
@ -9293,15 +9301,9 @@ def get_artist_enhanced_detail(artist_id):
|
|||
if album.get('thumb_url'):
|
||||
album['thumb_url'] = fix_artist_image_url(album['thumb_url'])
|
||||
|
||||
# Include server type for sync option
|
||||
# Include server type for sync option — engine routes to active client.
|
||||
active_server = config_manager.get_active_media_server()
|
||||
server_connected = False
|
||||
if active_server == 'plex':
|
||||
server_connected = plex_client.is_connected()
|
||||
elif active_server == 'jellyfin':
|
||||
server_connected = jellyfin_client.is_connected()
|
||||
elif active_server == 'navidrome':
|
||||
server_connected = navidrome_client.is_connected()
|
||||
server_connected = media_server_engine.is_connected() if media_server_engine else False
|
||||
result['server_type'] = active_server if server_connected else None
|
||||
|
||||
return jsonify(result)
|
||||
|
|
|
|||
Loading…
Reference in a new issue