Gate 0.0.27: de statuskaart loog na elke herstart. Relay 0.5.4: Status naar rechts

De melding van de gebruiker was "Not answering" met [Errno 111] Connection refused, terwijl de
gateway van buiten gewoon werkte. Het was een startvolgorde en geen storing:

1. de compose laat `server` ná de agent starten (depends_on: [agent]), want nginx lost
   http://agent:8000 bij het starten op en breekt af op een onbekende naam;
2. build_status draait meteen bij het opstarten, vóór de eerste WAKE.wait;
3. de branch die de meting uitstelt hing alleen aan `reloaded`, en die is bij een herstart met een
   ongewijzigd certificaat False, dus er werd gemeten;
4. nginx luisterde toen nog niet op 50022;
5. en het bleef staan, want de volgende meting kwam pas na SELF_CHECK_INTERVAL.

Twee reparaties, elk voor een helft. De eerste ronde van een proces meet niet maar zet `pending`
(die toestand heeft geen `at`, dus de ronde daarna meet gewoon), en na een mislukking wordt er na
GATE_SELF_CHECK_RETRY (60s) opnieuw gemeten in plaats van na 300. Een geslaagde meting blijft op
300, want dat is de waarde die zelden verandert en die het activiteitenlog belast.

De fout zat er sinds de zelfcontrole bestaat (27-08-2026) en was alleen binnen vijf minuten na een
herstart te zien. Mutatie-getest: de eerste-rondebranch uitschakelen laat twee tests omvallen, de
snelle herhaling uitschakelen precies één.

Relay: de statuswidget staat nu rechts in de bovenste rij en heet Status in plaats van Relay, gelijk
aan Electrum Gate. De twee pagina's zijn één app store en horen op dezelfde manier te lezen, en dit
is de widget die als enige begrijpelijk is zonder buur. De id's relay-state en relay-sub blijven.

Suite groen: 54 + 28 + 65 + 39 + 43 + 22 + 115.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Harmen
2026-08-31 12:14:37 +02:00
co-authored by Claude Opus 5
parent 63f1557713
commit 5ee21b10e7
8 changed files with 234 additions and 15 deletions
+52 -1
View File
@@ -66,6 +66,17 @@ TLS_PORT = int(os.environ.get("GATE_TLS_PORT", "50022"))
# er sowieso gemeten.
TLS_HOST = os.environ.get("GATE_TLS_HOST", "server")
SELF_CHECK_INTERVAL = int(os.environ.get("GATE_SELF_CHECK_INTERVAL", "300"))
# Na een MISLUKTE meting sneller opnieuw kijken dan na een geslaagde. Toegevoegd
# op 31-08-2026, samen met de overgeslagen eerste ronde hieronder; de aanleiding
# staat daar.
#
# De 300 seconden hierboven bestaan om het activiteitenlog niet vol te schrijven
# met onze eigen sessies, en dat argument weegt hier minder zwaar: een mislukking
# is juist de meting die je wilt herhalen, en een storing die een uur duurt is
# zestig extra regels waard. Een geslaagde meting blijft op 300, want dat is de
# waarde die zelden verandert.
SELF_CHECK_RETRY = int(os.environ.get("GATE_SELF_CHECK_RETRY", "60"))
INTERVAL = int(os.environ.get("GATE_INTERVAL", "60"))
API_PORT = int(os.environ.get("GATE_API_PORT", "8000"))
HISTORY_SECONDS = 24 * 3600
@@ -674,6 +685,18 @@ SELF_CHECK_NOTES = {
}
def self_check_wacht(previous_self):
"""Hoeveel seconden er tussen deze en de vorige meting moet zitten.
Alleen `ok` en `off` zijn rustige toestanden. `failed` en `wrong-certificate`
zijn allebei iets waar de gebruiker wat aan doet, en dan hoort de pagina
binnen een minuut te volgen in plaats van binnen vijf.
"""
if previous_self.get("state") in ("failed", "wrong-certificate"):
return SELF_CHECK_RETRY
return SELF_CHECK_INTERVAL
def probe_self(active):
"""Antwoordt de eigen TLS-poort, en met het gekozen certificaat?
@@ -912,7 +935,16 @@ def write_status(status):
os.replace(tmp, STATUS_FILE)
# Waar of onwaar voor de duur van dit proces; `build_status` zet hem bij de eerste
# aanroep om. Zie de toelichting in die functie bij de zelfcontrole.
EERSTE_RONDE = True
def build_status(events):
global EERSTE_RONDE
eerste_ronde = EERSTE_RONDE
EERSTE_RONDE = False
now = int(time.time())
previous = read_previous()
@@ -966,7 +998,26 @@ def build_status(events):
# geeft juist de interessantste meting die er is, want een herlading die
# niet aankomt is precies wat deze controle moet vinden.
self_check = {"state": "pending"}
elif now - int(previous_self.get("at") or 0) >= SELF_CHECK_INTERVAL:
elif eerste_ronde:
# DE EERSTE RONDE VAN DIT PROCES MEET NIET, en dat is geen voorzichtigheid
# maar een zekerheid (gemeld door de gebruiker, 31-08-2026).
#
# De compose laat `server` ná de agent starten (`depends_on: [agent]`,
# want nginx lost `http://agent:8000` bij het starten op en breekt af op
# een onbekende naam). Deze functie draait meteen bij het opstarten, vóór
# de eerste `WAKE.wait`. Op dat moment luistert nginx dus gegarandeerd nog
# niet op de TLS-poort, en de meting levert `[Errno 111] Connection
# refused` op.
#
# Dat op zichzelf zou een schoonheidsfoutje zijn; het probleem was dat het
# BLEEF STAAN. De volgende meting kwam pas na SELF_CHECK_INTERVAL, dus na
# elke herstart of update las de statuskaart vijf minuten lang "Not
# answering" terwijl er niets aan de hand was.
#
# `pending` heeft geen `at`, dus de rem hieronder laat de vólgende ronde
# gewoon meten: een minuut later staat er een echte uitkomst.
self_check = {"state": "pending"}
elif now - int(previous_self.get("at") or 0) >= self_check_wacht(previous_self):
self_check = probe_self(active)
if self_check.get("state") != "off":
# Ook bij een mislukking: een geweigerde handdruk is voor nginx nog