feat: add non-blocking datastore refresh with dedicated lock and improve service worker offline handling

Add datastore_refresh_lock to prevent concurrent refresh operations. Extract refresh_datastore_storage() function with non-blocking lock acquisition using acquire(blocking=False). Update datastore_snapshot() to spawn background thread for refresh when cache is stale but return immediately with cached data. Add offline fallback HTML page to service worker for navigate requests with 503 status for
This commit is contained in:
nessi committed 2026-08-21 20:55:19 +02:00
1 parent 1882d4e137
commit 5d7e452aaf
3 files changed
+30 -10

No files matched your search

+21 -6
View File
@@ -82,6 +82,7 @@ previous_cpu = None
service_status_lock = threading.Lock()
service_check_executor = ThreadPoolExecutor(max_workers=16)
datastore_cache_lock = threading.Lock()
datastore_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()
@@ -532,18 +533,32 @@ def raid_status():
"finish": format_remaining_time(finish_match.group(1)) if finish_match else "—", "speed": format_transfer_rate(speed_match.group(1)) if speed_match else "—"},
"error": None if array_line or mdadm_output else (mdadm_error or mdstat_error or "RAID-Status nicht verfügbar"), "updated_at": time.time()}
def datastore_snapshot():
now = time.time()
with datastore_cache_lock:
if datastore_cache["snapshot"] is None or now - datastore_cache["stored_at"] >= max(30, STORAGE_CACHE_SECONDS):
fresh_storage = scan_datastore_storage()
def refresh_datastore_storage():
if not datastore_refresh_lock.acquire(blocking=False):
return
try:
fresh_storage = scan_datastore_storage()
with datastore_cache_lock:
if fresh_storage.get("error") and datastore_cache["snapshot"]:
datastore_cache["snapshot"] = dict(datastore_cache["snapshot"])
datastore_cache["snapshot"]["stale"] = True
datastore_cache["snapshot"]["warning"] = fresh_storage["error"]
else:
datastore_cache["snapshot"] = fresh_storage
datastore_cache["stored_at"] = now
datastore_cache["stored_at"] = time.time()
finally:
datastore_refresh_lock.release()
def datastore_snapshot():
now = time.time()
with datastore_cache_lock:
storage = datastore_cache["snapshot"]
refresh_due = storage is None or now - datastore_cache["stored_at"] >= max(30, STORAGE_CACHE_SECONDS)
if storage is None:
refresh_datastore_storage()
elif refresh_due:
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: