Agent-Board verliert keine Ereignisse mehr. Eine Fallstudie.
Agent-Board zeigt live, was meine Claude-Code-Agents tun. Jeder Schritt eines Agents landet als eine Zeile in einer Datei, und das Board liest diese Datei mit. Wird sie zu groß, kürze ich sie. Genau dabei sind Ereignisse verloren gegangen.
- Problem: Beim Kürzen der Datei fehlten Ereignisse oder es entstanden halbe Zeilen.
- Ursache: Mehrere Agents schreiben gleichzeitig, und das Kürzen lief ohne Absprache dazwischen.
- Lösung: eine Sperre ohne Bibliothek, Kürzen über eine Temp-Datei und ein Server, der nach dem Kürzen an der richtigen Stelle weiterliest.
Das Problem
Jeder Hook von Claude Code hängt eine Zeile JSON an events.jsonl an. Ab 5 MB behält das Board nur die neuesten Zeilen. Zwei Dinge gingen dabei schief: Gleichzeitige Hooks schrieben mitten in eine gerade neu geschriebene Datei, dadurch entstanden halbe JSON-Zeilen. Und der Server, der die Datei live an den Browser schickt, verlor nach dem Kürzen das Ereignis direkt danach, zum Beispiel ein Agent fertig
.
Entscheidung 1: Eine Sperre, aber ohne Abhängigkeit
Agent-Board hat keine einzige Abhängigkeit, und das soll so bleiben. Statt einer Lock-Bibliothek nutze ich, dass das Anlegen eines Ordners atomar ist: Wer mkdir zuerst schafft, darf kürzen und schreiben. Alle anderen warten kurz.
Entscheidung 2: Lieber ohne Sperre schreiben als den Agent blockieren
Ein Hook darf Claude Code nie aufhalten. Deshalb wartet er höchstens 2 Sekunden auf die Sperre und schreibt danach trotzdem. Bleibt eine Sperre von einem abgestürzten Prozess liegen, wird sie nach 10 Sekunden als veraltet entfernt. Das ist bewusst ein Kompromiss: In einem sehr seltenen Fall kann wieder eine Zeile kaputtgehen, dafür hängt nie ein Agent.
Entscheidung 3: Erst Temp-Datei, dann umbenennen
Die gekürzte Datei wird zuerst in eine Temp-Datei geschrieben und dann mit einem Schritt umbenannt. So liest der Server nie eine halb geschriebene Datei. Unter Windows scheitert das Umbenennen, solange der Server die Datei offen hat. Dann wird eben beim nächsten Mal gekürzt, statt einen Fehler zu werfen. Außerdem darf nur der eigene Benutzer die Datei lesen und schreiben, weil darin steht, woran man gerade arbeitet.
Wie ich weiß, dass es hält
Drei neue Tests: Der Server macht nach dem Kürzen an der richtigen Stelle weiter, 30 gleichzeitige Hooks genau an der 5-MB-Grenze erzeugen keine halbe Zeile, und ein echter Live-Stream zum Browser verliert kein Ereignis. Beim Zusammenführen ist mir ein Test aufgefallen, der manchmal grundlos fehlschlug, weil er fest 400 ms gewartet hat. Jetzt wartet er, bis der Server wirklich bereit ist.
Was ich daraus mitnehme
Gleichzeitigkeit ist der Ort, an dem Fehler sich verstecken, weil sie nur manchmal auftreten. Ein Test, der nur manchmal fehlschlägt, ist kein Pech, sondern ein Hinweis. Und eine gute Lösung schreibt ihren Kompromiss dazu, damit man ihn später nicht für einen Fehler hält.
Code, Tests und der Pull Request sind öffentlich. Prüf gern selbst nach.