I-4: distinguish a mirror that never ran from one that is behind

Gitea reports the epoch for 'not yet synced', which arithmetic turns into a
56-year lag and a confident 'degraded'. Collapsing those two states is how a
backup that was never made gets read as a backup that is merely stale — which
is the more dangerous direction, because 'behind' sounds survivable.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Grant Whitmer
2026-08-11 16:16:05 -04:00
parent da257652c2
commit a2430de94d
3 changed files with 23 additions and 2 deletions

View File

@@ -514,6 +514,7 @@ async def mirror_status(
"healthy": "A second copy of this project is up to date.",
"degraded": "The second copy is behind. Your work here is safe.",
"absent": "There is no second copy of this project yet.",
"pending": "The second copy is set up and hasn't run yet.",
"unconfigured": "Off-site copies aren't switched on yet.",
"unknown": "We can't tell how the second copy is doing right now.",
}[status["state"]]

View File

@@ -154,8 +154,18 @@ class MirrorService:
except ValueError:
lag = None
# A mirror that has NEVER run is not the same thing as one that is
# behind, and collapsing the two is how a backup that was never made
# gets read as a backup that is merely stale. Gitea reports the epoch
# for "not yet", which arithmetic turns into a 56-year lag and a
# confident "degraded".
never_synced = not last or last.startswith("1970-01-01")
# I-4: lag over the threshold is a P2, not a shrug.
if lag is None:
if never_synced:
state = "pending"
lag = None
elif lag is None:
state = "unknown"
elif lag > self._s.mirror_lag_p2_seconds:
state = "degraded"
@@ -164,6 +174,6 @@ class MirrorService:
return {
"state": state,
"lag_seconds": lag,
"last_success_at": last,
"last_success_at": None if never_synced else last,
"remote": m.get("remote_address"),
}

View File

@@ -383,3 +383,13 @@ def test_owner_namespace_is_derived_from_the_repo_not_the_caller():
body = src[src.index("async def list_versions") : src.index("async def create_grant")]
assert "_repo_owner_login(repo)" in body
assert "_owner_login(caller)" not in body
def test_i04_never_synced_is_not_reported_as_merely_behind():
"""Collapsing 'never ran' into 'behind' is how a backup that was never made
gets read as a backup that is merely stale. Gitea reports the epoch for
'not yet', which arithmetic turns into a 56-year lag and a confident
'degraded'."""
src = (ROOT / "api" / "app" / "services" / "mirror.py").read_text()
assert "never_synced" in src
assert '"pending"' in src