mirror of
https://github.com/kuhyx/screen-locker.git
synced 2026-11-10 19:07:16 +01:00
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
51 lines
1.6 KiB
Python
51 lines
1.6 KiB
Python
"""Which workout backends could not be read on this run, and why.
|
|
|
|
Split out of :mod:`screen_locker._sync_client` to keep every file under the
|
|
250-line cap. Re-exported from there, so existing importers and their patch
|
|
targets are unchanged.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class DegradedSource:
|
|
"""A workout backend that could not be read on this run.
|
|
|
|
``reason`` is the backend's own error text, kept verbatim so the status
|
|
view and the lock decision can quote something actionable rather than a
|
|
generic "sync problem".
|
|
"""
|
|
|
|
name: str
|
|
reason: str
|
|
|
|
|
|
# Process-scoped rather than persisted: it describes THIS run's ability to
|
|
# read, and a stale marker from an earlier run would be worse than none. The
|
|
# lock chain and the pull both happen in one process, so this survives exactly
|
|
# as long as it is true.
|
|
_degraded: list[DegradedSource] = []
|
|
|
|
|
|
def degraded_sources() -> list[DegradedSource]:
|
|
"""Return the backends that failed to answer during this run."""
|
|
return list(_degraded)
|
|
|
|
|
|
def clear_degraded_sources() -> None:
|
|
"""Forget recorded failures (called at the start of a fresh check)."""
|
|
_degraded.clear()
|
|
|
|
|
|
def _record_degraded(name: str, reason: str) -> None:
|
|
"""Note that *name* could not be read, so callers can stop guessing.
|
|
|
|
Logging alone was not enough: on 2026-08-24 the warning was emitted, the
|
|
Firebase read was skipped, and the lock decision still reported
|
|
"0 workouts this week" as though the source had answered "none".
|
|
"""
|
|
_degraded.append(DegradedSource(name, reason))
|