Media Max
Die Verbindung ist momentan unterbrochen. Bitte erneut laden.
diff --git a/app.py b/app.py index f653878..49a08e0 100644 --- a/app.py +++ b/app.py @@ -83,6 +83,7 @@ service_status_lock = threading.Lock() service_check_executor = ThreadPoolExecutor(max_workers=16) datastore_cache_lock = threading.Lock() datastore_refresh_lock = threading.Lock() +raid_refresh_lock = threading.Lock() datastore_cache = {"stored_at": 0.0, "snapshot": None, "raid": None, "raid_at": 0.0} raid_log_state = None hardware_log_once = set() @@ -549,6 +550,25 @@ def refresh_datastore_storage(): finally: datastore_refresh_lock.release() +def refresh_raid_status(): + if not raid_refresh_lock.acquire(blocking=False): + return + try: + current = raid_status() + with datastore_cache_lock: + if current.get("status") == "failed" and current.get("error") and datastore_cache.get("raid"): + cached = dict(datastore_cache["raid"]) + cached["stale"] = True + cached["warning"] = "Vorübergehend keine aktuelle RAID-Antwort." + datastore_cache["raid"] = cached + else: + datastore_cache["raid"] = current + datastore_cache["raid_at"] = time.time() + except Exception as exc: + log.error("RAID-Refresh fehlgeschlagen: %s", error_summary(exc)) + finally: + raid_refresh_lock.release() + def datastore_snapshot(): now = time.time() with datastore_cache_lock: @@ -560,15 +580,14 @@ def datastore_snapshot(): threading.Thread(target=refresh_datastore_storage, name="datastore-refresh", daemon=True).start() with datastore_cache_lock: storage = datastore_cache["snapshot"] - current_raid = raid_status() with datastore_cache_lock: - if current_raid.get("status") == "failed" and current_raid.get("error") and datastore_cache.get("raid") and now - datastore_cache.get("raid_at", 0) < 60: - current_raid = dict(datastore_cache["raid"]) - current_raid["stale"] = True - current_raid["warning"] = "Vorübergehend keine aktuelle RAID-Antwort; letzter gültiger Stand wird angezeigt." - elif current_raid.get("status") != "failed": - datastore_cache["raid"] = dict(current_raid) - datastore_cache["raid_at"] = now + current_raid = datastore_cache.get("raid") + raid_age = now - datastore_cache.get("raid_at", 0) + if current_raid is None: + threading.Thread(target=refresh_raid_status, name="raid-refresh", daemon=True).start() + current_raid = {"device": RAID_DEVICE, "status": "unknown", "label": "WIRD GELADEN", "error": "RAID-Status wird geladen"} + elif raid_age >= 5: + threading.Thread(target=refresh_raid_status, name="raid-refresh", daemon=True).start() return {"storage": storage, "raid": current_raid, "io_pressure": io_pressure(), "cache_seconds": STORAGE_CACHE_SECONDS} def cpu_usage_percent(): diff --git a/static/sw.js b/static/sw.js index 6a62cb3..e9d2e00 100644 --- a/static/sw.js +++ b/static/sw.js @@ -1,4 +1,4 @@ -const CACHE_NAME = 'media-max-shell-v6'; +const CACHE_NAME = 'media-max-shell-v7'; const SHELL = ['/static/media-mark.svg', '/static/media-mark-192.png', '/static/media-mark-512.png', '/static/manifest.json']; self.addEventListener('install', event => { @@ -16,10 +16,11 @@ self.addEventListener('fetch', event => { if (request.method !== 'GET') return; const url = new URL(request.url); if (url.pathname.startsWith('/api/')) return; + // Navigation requests must stay real network requests. Returning an + // offline document here can mask backend errors and make the app appear + // disconnected after a scan/reload. + if (request.mode === 'navigate') return; event.respondWith(fetch(request).catch(() => { - if (request.mode === 'navigate') { - return new Response('
Die Verbindung ist momentan unterbrochen. Bitte erneut laden.