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:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user