Reduce Spotify status polling
- cache Spotify auth and rate-limit status separately from the generic metadata source snapshot - refresh Spotify status only on explicit auth/disconnect/test paths or after the TTL expires - keep the legacy OAuth callback paths aligned with the same invalidation helper
This commit is contained in:
parent
e2bd0e1871
commit
3c7187fb32
1 changed files with 39 additions and 14 deletions
|
|
@ -821,6 +821,24 @@ _status_cache_timestamps: dict[str, float] = {
|
|||
'soulseek': 0,
|
||||
}
|
||||
STATUS_CACHE_TTL = 120
|
||||
SPOTIFY_STATUS_TTL_ACTIVE = 15
|
||||
SPOTIFY_STATUS_TTL_IDLE = 300
|
||||
|
||||
_spotify_status_cache = {
|
||||
'connected': False,
|
||||
'authenticated': False,
|
||||
'rate_limited': False,
|
||||
'rate_limit': None,
|
||||
'post_ban_cooldown': None,
|
||||
}
|
||||
_spotify_status_timestamp = 0.0
|
||||
|
||||
|
||||
def _invalidate_metadata_status_caches():
|
||||
"""Mark the metadata-source and Spotify status snapshots stale."""
|
||||
global _spotify_status_timestamp
|
||||
_status_cache_timestamps['metadata_source'] = 0
|
||||
_spotify_status_timestamp = 0
|
||||
|
||||
dev_mode_enabled = False
|
||||
_hydrabase_ws = None
|
||||
|
|
@ -4155,7 +4173,7 @@ def handle_settings():
|
|||
if tidal_enrichment_worker:
|
||||
tidal_enrichment_worker.client = tidal_client
|
||||
# Invalidate status cache so next poll reflects new settings (e.g. fallback source change)
|
||||
_status_cache_timestamps['metadata_source'] = 0
|
||||
_invalidate_metadata_status_caches()
|
||||
logger.info("Service clients re-initialized with new settings.")
|
||||
return jsonify({"success": True, "message": "Settings saved successfully."})
|
||||
except Exception as e:
|
||||
|
|
@ -4772,8 +4790,7 @@ def test_connection_endpoint():
|
|||
if success:
|
||||
current_time = time.time()
|
||||
if service == 'spotify':
|
||||
spotify_session_active = spotify_client.is_spotify_authenticated() if spotify_client else False
|
||||
_status_cache_timestamps['metadata_source'] = 0
|
||||
_invalidate_metadata_status_caches()
|
||||
logger.info("Updated Spotify status cache after successful test")
|
||||
elif service in ['plex', 'jellyfin', 'navidrome', 'soulsync']:
|
||||
_status_cache['media_server']['connected'] = True
|
||||
|
|
@ -4937,8 +4954,7 @@ def test_dashboard_connection_endpoint():
|
|||
if success:
|
||||
current_time = time.time()
|
||||
if service == 'spotify':
|
||||
spotify_session_active = spotify_client.is_spotify_authenticated() if spotify_client else False
|
||||
_status_cache_timestamps['metadata_source'] = 0
|
||||
_invalidate_metadata_status_caches()
|
||||
logger.info("Updated Spotify status cache after successful dashboard test")
|
||||
elif service in ['plex', 'jellyfin', 'navidrome', 'soulsync']:
|
||||
_status_cache['media_server']['connected'] = True
|
||||
|
|
@ -5817,7 +5833,7 @@ def spotify_callback():
|
|||
return _spotify_auth_result_page("Your personal Spotify account is now connected. You can close this window.", authenticated=True)
|
||||
if profile_client:
|
||||
profile_client._invalidate_auth_cache()
|
||||
_status_cache_timestamps['metadata_source'] = 0
|
||||
_invalidate_metadata_status_caches()
|
||||
add_activity_item("", "Spotify Auth Warning", f"Profile {profile_id_from_state} completed OAuth but Spotify did not confirm an authenticated session", "Now")
|
||||
return _spotify_auth_result_page(
|
||||
"Spotify authorization completed, but SoulSync could not confirm an authenticated Spotify session for this profile. You can close this window and try Authenticate again.",
|
||||
|
|
@ -5853,7 +5869,7 @@ def spotify_callback():
|
|||
_clear_rate_limit()
|
||||
spotify_client._invalidate_auth_cache()
|
||||
# Invalidate status cache so next poll picks up the new connection
|
||||
_status_cache_timestamps['metadata_source'] = 0
|
||||
_invalidate_metadata_status_caches()
|
||||
# Refresh enrichment worker's client so it picks up new auth
|
||||
if spotify_enrichment_worker and hasattr(spotify_enrichment_worker, 'client'):
|
||||
spotify_enrichment_worker.client.reload_config()
|
||||
|
|
@ -5863,7 +5879,7 @@ def spotify_callback():
|
|||
else:
|
||||
logger.warning("Spotify OAuth token exchange succeeded but authentication validation failed")
|
||||
spotify_client._invalidate_auth_cache()
|
||||
_status_cache_timestamps['metadata_source'] = 0
|
||||
_invalidate_metadata_status_caches()
|
||||
add_activity_item("", "Spotify Auth Warning", "OAuth completed, but Spotify did not confirm an authenticated session", "Now")
|
||||
return _spotify_auth_result_page(
|
||||
"Spotify authorization completed, but SoulSync could not confirm an authenticated Spotify session. You can close this window and try Authenticate again.",
|
||||
|
|
@ -5892,7 +5908,7 @@ def spotify_disconnect():
|
|||
source_label = get_metadata_source_label(active_source)
|
||||
if configured_source == 'spotify':
|
||||
config_manager.set('metadata.fallback_source', active_source)
|
||||
_status_cache_timestamps['metadata_source'] = 0
|
||||
_invalidate_metadata_status_caches()
|
||||
add_activity_item("", "Spotify Disconnected", f"Using {source_label} for metadata", "Now")
|
||||
return jsonify({
|
||||
'success': True,
|
||||
|
|
@ -32027,7 +32043,7 @@ def start_oauth_callback_servers():
|
|||
_clear_rate_limit()
|
||||
spotify_client._invalidate_auth_cache()
|
||||
# Invalidate status cache so next poll picks up the new connection
|
||||
_status_cache_timestamps['metadata_source'] = 0
|
||||
_invalidate_metadata_status_caches()
|
||||
# Refresh enrichment worker's client so it picks up new auth
|
||||
if spotify_enrichment_worker and hasattr(spotify_enrichment_worker, 'client'):
|
||||
spotify_enrichment_worker.client.reload_config()
|
||||
|
|
@ -32040,7 +32056,7 @@ def start_oauth_callback_servers():
|
|||
else:
|
||||
_oauth_logger.warning("Spotify token exchange succeeded but authentication validation failed")
|
||||
spotify_client._invalidate_auth_cache()
|
||||
_status_cache_timestamps['metadata_source'] = 0
|
||||
_invalidate_metadata_status_caches()
|
||||
add_activity_item("", "Spotify Auth Warning", "OAuth completed, but Spotify did not confirm an authenticated session", "Now")
|
||||
self.send_response(200)
|
||||
self.send_header('Content-type', 'text/html')
|
||||
|
|
@ -34029,7 +34045,15 @@ def _build_status_payload():
|
|||
|
||||
def _build_spotify_status_payload():
|
||||
"""Build a Spotify-specific status snapshot for auth and rate-limit state."""
|
||||
status_data = {}
|
||||
import time
|
||||
|
||||
global _spotify_status_timestamp
|
||||
current_time = time.time()
|
||||
configured_source = config_manager.get('metadata.fallback_source', 'deezer') or 'deezer'
|
||||
ttl = SPOTIFY_STATUS_TTL_ACTIVE if configured_source == 'spotify' else SPOTIFY_STATUS_TTL_IDLE
|
||||
|
||||
if _spotify_status_timestamp and current_time - _spotify_status_timestamp <= ttl:
|
||||
return dict(_spotify_status_cache)
|
||||
|
||||
try:
|
||||
# Always include fresh rate limit info because it can change independently of cache TTL.
|
||||
|
|
@ -34038,17 +34062,18 @@ def _build_spotify_status_payload():
|
|||
cooldown_remaining = spotify_client.get_post_ban_cooldown_remaining() if spotify_client else 0
|
||||
authenticated = spotify_client.is_spotify_authenticated() if spotify_client else False
|
||||
|
||||
status_data.update({
|
||||
_spotify_status_cache.update({
|
||||
'connected': authenticated,
|
||||
'authenticated': authenticated,
|
||||
'rate_limited': is_rate_limited,
|
||||
'rate_limit': rate_limit_info,
|
||||
'post_ban_cooldown': cooldown_remaining if cooldown_remaining > 0 else None,
|
||||
})
|
||||
_spotify_status_timestamp = current_time
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return status_data
|
||||
return dict(_spotify_status_cache)
|
||||
|
||||
def _build_watchlist_count_payload(profile_id=1):
|
||||
"""Build the same payload used by GET /api/watchlist/count."""
|
||||
|
|
|
|||
Loading…
Reference in a new issue