Autostart durch Manager, mit Sicherungsautomat (#528)

Entschieden vom Benutzer am 2026-09-08. Der Schalter heisst
autostartByManager und steht in InstanceSettings.json - bei der Instanz,
nicht beim Manager.

ZWEI DINGE IN EINEM SCHALTER, weil es dieselbe Zusage ist: Der Manager
startet diese Instanz, wenn er selbst hochkommt, und er startet sie wieder,
wenn sie abstuerzt. Ohne den Schalter ruehrt er nichts an - ein Manager,
der nach einem Neustart der Maschine alles hochfaehrt, was er findet,
startet auch das, was jemand mit Absicht angehalten hat. Ausgeschaltet
vorbelegt.

DER SICHERUNGSAUTOMAT ist der eigentliche Inhalt. Wieder hochzufahren ist
die einfache Haelfte; die schwierige ist zu erkennen, wann man es lassen
muss. Nach drei Neustarts in zehn Minuten (maxRestartsInWindow,
restartWindowMinutes) setzt der Manager aus und meldet es. Die Instanz
bleibt dann aus, bis jemand sie von Hand startet - und dieser Start raeumt
den Zaehler ab, denn wer von Hand startet, hat entweder etwas geaendert
oder weiss, was er tut. Das Zeitfenster wandert: Eine Instanz, die einmal
im Monat abstuerzt und wieder hochkommt, laeuft nie in die Grenze.

Nur bei einem Absturz, nicht wenn eine Instanz verstummt. Eine stumme
Instanz lebt noch; sie neu zu starten hiesse, sie erst abzuschiessen, und
ob der Manager das von sich aus darf, ist nicht entschieden. Als offene
Frage aufgeschrieben - genau dieser Zustand war der Anlass des Vorhabens.

Der Schalter steht bei der Instanz, weil er eine Eigenschaft dieser Instanz
ist und weil die Instanzdatei dem Instanzprozess gehoert: Sie vom Manager
schreiben zu lassen, waehrend die Instanz laeuft, waeren zwei Schreiber auf
einer Datei. Der Manager liest ihn nur; geaendert wird er auf der
Einstellungsseite der Instanz.

EIN DEFEKT, den erst diese Tests gezeigt haben: StartAsync gab "laeuft
schon" zurueck, wenn die Aufsicht die Instanz fuer laufend hielt - ohne
nachzusehen. Zwischen zwei Aufsichtsdurchgaengen liegen aber Sekunden, und
in denen kann sie wegbrechen. Wer in dieser Luecke "starten" verlangte,
bekam einen Erfolg, hinter dem nichts stand, und der naechste Durchgang
meldete einen Absturz, den niemand mehr erwartete. Jetzt wird gefragt,
bevor zugestimmt wird.

UND EIN TESTDOUBLE, das die Wirklichkeit nicht abbildete: Der falsche
Socket antwortete unabhaengig davon, ob ein Prozess lief. Damit war jeder
Testaufbau, der die Antwort vor dem Hochfahren hinterlegte, stillschweigend
ein anderer Test als beabsichtigt - eine Antwort sagt dem Manager "laeuft
bereits", er uebernimmt, und der Starter wird nie angefasst. Dreimal
passiert. Der falsche Socket haengt jetzt am falschen Starter.

Sicherungen im Manager sind als #530 zurueckgestellt, mit Ausloeser.
Vorab entschieden ist dort nur eines: Zurueckspielen ausschliesslich bei
inaktiver Instanz.

19 neue Tests. Build ohne Warnungen, 793 Tests gruen, 8 uebersprungen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Richard
2026-09-09 00:01:52 +02:00
co-authored by Claude Opus 5
parent db7abf699f
commit 7d4e8b3096
15 changed files with 757 additions and 30 deletions
+61 -14
View File
@@ -269,26 +269,32 @@ Produktions- und eine Testinstanz nebeneinander betreiben.
## 7 — Noch zu klären
**Sicherungen im Manager?** Dafür spricht viel: Die gemeinsame Rotation aus 1.2
verschwände, und eine Sicherung ließe sich auch von einer Instanz ziehen, die
gerade nicht läuft. Dagegen spricht eine Falle — **eine Sicherung
zurückzuspielen heißt, in ein Instanzverzeichnis zu schreiben, während die
Instanz womöglich läuft.** Das muss den Prozess erst anhalten, sonst schreibt man
unter einer offenen `state.db` das Dateisystem um. Wenn es kommt, dann mit dieser
Reihenfolge: anhalten, zurückspielen, starten — und nie ohne Rückfrage.
**Sicherungen im Manager — zurückgestellt** (2026-09-08, #530). Erst soll der Rest
laufen. Die gemeinsame Aufbewahrung ist mit Stufe 1 ohnehin erledigt, der
verbleibende Gewinn ist damit kleiner als anfangs gedacht: Es bliebe, auch von
einer Instanz sichern zu können, die gerade nicht läuft.
**Eine Sache ist daran aber schon entschieden:** Zurückspielen heißt, in ein
Instanzverzeichnis zu schreiben, und das darf **ausschließlich bei inaktiver
Instanz** geschehen — sonst schreibt man unter einer offenen `state.db` das
Dateisystem um. Reihenfolge, wenn es kommt: anhalten, zurückspielen, starten. Und
nie ohne Rückfrage. Der Manager kann das inzwischen: Er kennt den Zustand jeder
Instanz über ihren Socket und hält sie geordnet an.
**Wie stellt eine Instanz fest, dass ein Manager da ist?** Vorschlag: Der Manager
startet sie und gibt ihr den Socketpfad mit; die Instanz verbindet sich einmal
zurück und beendet sich, wenn das nicht gelingt. Kein Selbstzweck-Handschlag,
sondern die Prüfung aus E-M3.
**Startet der Manager eine abgestürzte Instanz wieder?** Bisher nicht — er merkt es und
meldet es, mehr nicht. Dafür spricht, dass eine Instanz, die nachts um drei abstürzt, bis
zum Morgen tot bleibt. Dagegen spricht die Schleife: Eine Instanz, die an einer kaputten
Konfiguration scheitert, stürzt beim zehnten Versuch genauso ab wie beim ersten, und dann
hat man statt einer toten Instanz eine tote Instanz und ein volles Protokoll. Wenn es
kommt, dann mit Wartezeitverdopplung und einer Obergrenze, nach der er es sein lässt und
das meldet.
**Startet der Manager eine abgestürzte Instanz wieder? — Entschieden** (2026-09-08):
ja, aber nur, wenn die Instanz es verlangt. Der Schalter heißt „Autostart durch
Manager" und steht in der Instanzdatei; siehe Abschnitt 9.7.
**Was ist mit einer Instanz, die verstummt?** Der Autostart greift nur bei einem
Absturz. Eine stumme Instanz lebt noch — sie neu zu starten hieße, sie erst
abzuschießen, und ob der Manager das von sich aus tun darf, ist nicht entschieden.
Bis dahin meldet er sie und lässt sie stehen. Genau dieser Zustand war der Anlass
(1.1), insofern ist die Frage nicht akademisch.
**Der Aufhänger aus 1.1 ist nicht geklärt** (#529). Er verschwindet mit dem
Umbau vermutlich von selbst, weil es den Selbst-Neustart nicht mehr gibt — aber
@@ -648,3 +654,44 @@ Fenster (E-M2). Auf einer Maschine ohne Bildschirmsitzung gehört `false` hin.
| Prozess danach | **PID 18128, unverändert** — nichts neu gestartet |
Die letzte Zeile ist die Abnahmebedingung: kein Neustart mehr beim Wechseln.
### 9.7 Autostart durch Manager
Entschieden am 2026-09-08. Der Schalter heißt **`autostartByManager`** und steht in
`InstanceSettings.json` — bei der Instanz, nicht beim Manager.
**Zwei Dinge in einem Schalter, weil es dieselbe Zusage ist:** Der Manager startet diese
Instanz, wenn er selbst hochkommt, und er startet sie wieder, wenn sie abstürzt. Ohne den
Schalter rührt er nichts an — ein Manager, der nach einem Neustart der Maschine alles
hochfährt, was er findet, startet auch das, was jemand mit Absicht angehalten hat.
Ausgeschaltet vorbelegt.
**Der Sicherungsautomat ist der eigentliche Inhalt.** Wieder hochzufahren ist die einfache
Hälfte; die schwierige ist zu erkennen, wann man es lassen muss. Nach **drei Neustarts in
zehn Minuten** (`maxRestartsInWindow`, `restartWindowMinutes` in `manager.json`) setzt der
Manager aus und meldet es. Die Instanz bleibt dann aus, bis jemand sie von Hand startet —
und dieser Start räumt den Zähler ab, denn wer von Hand startet, hat entweder etwas
geändert oder weiß, was er tut.
Das Zeitfenster wandert: Eine Instanz, die einmal im Monat abstürzt und wieder hochkommt,
läuft nie in die Grenze — eine, die im Minutentakt fällt, sofort.
**Warum der Schalter bei der Instanz steht und nicht beim Manager:** Er ist eine
Eigenschaft dieser Instanz. Und die Instanzdatei gehört dem Instanzprozess — sie vom
Manager schreiben zu lassen, während die Instanz läuft, wären zwei Schreiber auf einer
Datei. Der Manager **liest** den Schalter; geändert wird er auf der Einstellungsseite der
Instanz.
**Ein Defekt, den erst diese Tests gezeigt haben.** `StartAsync` gab „läuft schon" zurück,
wenn die Aufsicht die Instanz für laufend hielt — ohne nachzusehen. Zwischen zwei
Aufsichtsdurchgängen liegen aber Sekunden, und in denen kann sie wegbrechen: Wer in dieser
Lücke „starten" verlangte, bekam einen Erfolg, hinter dem nichts stand, und der nächste
Durchgang meldete einen Absturz, den niemand mehr erwartete. Jetzt wird gefragt, bevor
zugestimmt wird.
**Und ein Testdouble, das die Wirklichkeit nicht abbildete.** Der falsche Socket antwortete
unabhängig davon, ob ein Prozess lief. Damit war jeder Testaufbau, der die Antwort vor dem
Hochfahren hinterlegte, stillschweigend ein anderer Test als beabsichtigt — dem Manager
sagt eine Antwort „diese Instanz läuft bereits", er übernimmt sie, und der Starter wird nie
angefasst. Das ist mir dreimal passiert. Der falsche Socket hängt jetzt am falschen
Starter: Er antwortet nur, wenn wirklich ein Prozess läuft.