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,
|
self,
|
||||||
registry: Optional[MediaServerRegistry] = None,
|
registry: Optional[MediaServerRegistry] = None,
|
||||||
active_server_resolver=None,
|
active_server_resolver=None,
|
||||||
|
clients: Optional[Dict[str, Any]] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize the engine.
|
"""Initialize the engine.
|
||||||
|
|
||||||
|
|
@ -56,9 +57,29 @@ class MediaServerEngine:
|
||||||
``config_manager.get_active_media_server``. Tests
|
``config_manager.get_active_media_server``. Tests
|
||||||
inject a custom resolver to switch active server
|
inject a custom resolver to switch active server
|
||||||
without touching real config.
|
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 = 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:
|
if active_server_resolver is None:
|
||||||
from config.settings import config_manager
|
from config.settings import config_manager
|
||||||
|
|
|
||||||
|
|
@ -603,6 +603,23 @@ try:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f" SoulSync library client failed to initialize: {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:
|
try:
|
||||||
soulseek_client = DownloadOrchestrator()
|
soulseek_client = DownloadOrchestrator()
|
||||||
logger.info(" Download orchestrator initialized")
|
logger.info(" Download orchestrator initialized")
|
||||||
|
|
@ -3460,23 +3477,14 @@ def get_status():
|
||||||
|
|
||||||
metadata_status = get_metadata_status_snapshot(spotify_client=spotify_client)
|
metadata_status = get_metadata_status_snapshot(spotify_client=spotify_client)
|
||||||
|
|
||||||
# Test media server - use EXISTING instances (they have internal caching)
|
# Test media server — engine reads active_server config + dispatches
|
||||||
# Media server clients already cache connection checks internally
|
# 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:
|
if current_time - _status_cache_timestamps['media_server'] > STATUS_CACHE_TTL:
|
||||||
media_server_start = time.time()
|
media_server_start = time.time()
|
||||||
media_server_status = False
|
media_server_status = (
|
||||||
if active_server == "plex" and plex_client:
|
media_server_engine.is_connected() if media_server_engine else False
|
||||||
# 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_response_time = (time.time() - media_server_start) * 1000
|
media_server_response_time = (time.time() - media_server_start) * 1000
|
||||||
_status_cache['media_server'] = {
|
_status_cache['media_server'] = {
|
||||||
'connected': media_server_status,
|
'connected': media_server_status,
|
||||||
|
|
@ -9293,15 +9301,9 @@ def get_artist_enhanced_detail(artist_id):
|
||||||
if album.get('thumb_url'):
|
if album.get('thumb_url'):
|
||||||
album['thumb_url'] = fix_artist_image_url(album['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()
|
active_server = config_manager.get_active_media_server()
|
||||||
server_connected = False
|
server_connected = media_server_engine.is_connected() if media_server_engine else 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()
|
|
||||||
result['server_type'] = active_server if server_connected else None
|
result['server_type'] = active_server if server_connected else None
|
||||||
|
|
||||||
return jsonify(result)
|
return jsonify(result)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue