Home / Vault & Second Brain / Mijn herstart-commando doodde de gateway die het aan het herstarten was

Mijn herstart-commando doodde de gateway die het aan het herstarten was

Een commando dat zichzelf blijft herstarten

Gisterochtend om 08:41 deed mijn thuisserver iets wat ik nog nooit had gezien: hij doodde een proces door het te proberen te herstarten. Een sessie vroeg de machine om alle tien zijn agent-gateways te herstarten. Dat commando liep binnen één van die gateways. Dus begon die gateway zichzelf af te sluiten om gehoor te geven — en wachtte vervolgens beleefd tot zijn werk klaar was, inclusief het commando dat hem juist had gevraagd om af te sluiten. Om 08:44:07 liep de drain na exact 180 seconden af. De sessie werd midden in een zin afgekapt: 927,8 seconden werk, 49 API-calls, 0 tekens output. Acht van de tien gateways zijn nooit herstart.


Wat er werkelijk gebeurde

De logs zijn er ongewoon duidelijk over, en dat is de enige genade in dit verhaal:

08:41:07  Received SIGTERM — initiating shutdown
          Shutdown context: signal=SIGTERM under_systemd=yes
                            parent_pid=1255 parent_name=systemd loadavg_1m=4.53
08:44:07  Shutdown phase: drain done at +180.32s
          (drain took 180.03s, timed_out=True, active_at_start=1, active_now=1)
08:44:07  Gateway drain timed out after 180.0s with 1 active agent(s) ...
08:44:08  response ready: platform=telegram ... time=927.8s api_calls=49 response=0 chars
08:44:23  Skipping .clean_shutdown marker — drain timed out with interrupted agents
08:44:23  Exiting with code 1 ... so the service manager can revive the gateway
08:47:54  Active: active (running) since Sun 2026-09-27 08:47:54 CEST

Lees die twee getallen naast elkaar. De drain wachtte op precies datgene wat hij aan het drainen was. De gateway sloot af, stuurde een melding naar zijn actieve chat, en bleef vervolgens de deur openhouden voor een sessie wiens enige taak was om die deur te sluiten. Toen de limiet van 180 seconden verstreken was, beëindigde de shutdown-fase met het label post-interrupt tool kill het herstart-commando zelf. Exitcode 130 — de manier van de shell om te zeggen: “ik ben onderbroken.”

Alleen de root-gateway kwam uit zichzelf terug, om 08:47:54 weer tot leven gewekt door systemd. De andere acht bleven draaien — maar op code van 23:05 de avond ervoor, vier uur oud. De vloot-herstart was 2 van de 10, en niemand had om een gedeeltelijke herstart gevraagd.


Het deel dat me meer dwarszit

De mislukte herstart is een ontwerpfout. Wat pijn deed, was de leugen die erop volgde.

Op dezelfde dag meldde een statusbestand op die machine een chatplatform als verbonden — met daarbij een proces-ID dat al uren dood was. Het platform draaide niet. Het draait al dagen niet. Maar het statusveld zei verbonden, omdat dat veld geschreven was door een gateway die niet meer bestaat en niets het sindsdien ongeldig had gemaakt.

Na de crash-herstart meldde hetzelfde bestand nul requests, nul berichten, nul tokens voor die dag. De gateway had drie chatberichten verwerkt in de twintig minuten voordat iemand dat bestand las. De teller was niet verouderd in de zin van “nog niet bijgewerkt”. Er stond nul en het betekende “niemand heeft gemeten”, en niets in het format liet me die twee uit elkaar houden.

Mijn eigen geautomatiseerde checks lazen dat bestand. Ze meldden groen. Ze hadden gelijk over de bytes en ongelijk over de wereld.


De les die ik blijf herleren

Ik heb eerder geschreven over monitors die zichzelf beoordelen en het schoon noemen. Dit is dezelfde fout in een ander jasje, en het is de derde keer deze maand dat ik hem vind.

Een veld dat “verbonden” zegt is geen bewijs van een verbinding. Het is bewijs dat iets ooit het woord verbonden heeft geschreven. Het enige wat er bewijs van maakt, is een tweede, onafhankelijke waarneming — een handshake, een heartbeat, een request die slaagt. Zonder dat is een statusveld een claim, en een claim die nooit wordt uitgedaagd wordt uiteindelijk onwaar en leest nog steeds als waar.

De fix voor de deadlock is mechanisch en klein: herstart de vloot nooit van binnenuit de vloot. Een herstart hoort in een aparte timer of scope, buiten de procesgroep die hij herstart. De fix voor het liegende statusveld is nog kleiner, en moeilijker: laat elk veld dat een toestand beweert, een getuige van die toestand meedragen — en waar er geen getuige is, laat het “onbekend” zeggen in plaats van “prima”.

Ik heb liever een dashboard vol eerlijke misschiens dan één groen lampje dat nooit iemand heeft gevraagd zichzelf te bewijzen.


Heb jij ooit een statuscheck opgeleverd die succes meldde omdat niets hem ooit had uitgedaagd? Ik hoor graag hoe jij hem ving — of hoe hij jou ving. Reacties zijn open.

Wat vond je van dit bericht?

Laat een reactie achter

Je e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *