Die Arbeit, die zweimal abbuchte
Ein Prüfpunkt ist ein gespeicherter Vermerk über die bereits fertige Arbeit. So kann eine lange Arbeit anhalten und neu beginnen, ohne alles zu wiederholen. Agenten laufen Minuten oder Stunden, und Prozesse sterben.
Eine Arbeit buchte fünf Bestellungen ab. Bei der dritten stürzte sie ab und startete wieder von vorn. Zwei Kunden zahlten doppelt.
Am Ende dieser Lektion
Notiz
Ich kann lange Arbeit sicher anhaltbar und fortsetzbar machen.
Schlüsselwörter
| Begriff | Was er bedeutet | Beispiel |
|---|---|---|
| Prüfpunkt | ein gespeicherter Vermerk über fertige Arbeit | |
| Idempotent | sicher zweimal ausführbar, mit einer Wirkung | |
| Fortsetzen | vom letzten Prüfpunkt aus weitermachen | |
| Nebenwirkung | eine Änderung außerhalb des Programms | eine Abbuchung |
| Ereignisprotokoll | eine Liste dessen, was geschah, der Reihe nach |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Ein Prüfpunkt sagt, was fertig ist
Schreiben Sie nach jedem Schritt seinen Namen in eine Datei oder Tabelle. Lesen Sie beim Start diesen Vermerk und überspringen Sie, was schon fertig ist.
Schreiben Sie vor einem Schritt einen Eintrag gestartet und danach einen Eintrag fertig. Dann kann ein Neustart einen nie begonnenen Schritt von einem mittendrin abgebrochenen unterscheiden.
Ausgearbeitetes Beispiel: wo ein Absturz liegen kann
| Der Absturz liegt | Das Protokoll sagt | Beim Fortsetzen |
|---|---|---|
| Vor dem Beginn des Schritts | Nichts darüber | Starten |
| Im Schritt, vor seiner Wirkung | Gestartet | Wiederholen |
| Nach seiner Wirkung, vor fertig | Gestartet | Wiederholen, die Wirkung wiederholt sich |
| Nach fertig | Fertig | Überspringen |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Die fortsetzbare Arbeit schreiben, Teil 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const fs = require(\"fs\");' 'const PRUEFPUNKT = \"demo/pruefpunkt.json\";' 'const LOG = \"demo/abbuchungen.log\";' 'const bestellungen = [\"B1\", \"B2\", \"B3\", \"B4\", \"B5\"];' 'const absturzBei = process.argv[2];' 'fs.mkdirSync(\"demo\", { recursive: true });' 'function laden() {' ' try { return JSON.parse(fs.readFileSync(PRUEFPUNKT, \"utf8\")); } catch (fehler) { return { fertig: [], gestartet: null }; }' '}' 'function speichern(zustand) { fs.writeFileSync(PRUEFPUNKT, JSON.stringify(zustand)); }' 'function abbuchen(id) {' ' const gesehen = fs.existsSync(LOG) ? fs.readFileSync(LOG, \"utf8\").split(\"\n\") : [];' ' if (gesehen.indexOf(id) >= 0) { console.log(id + \": schon abgebucht, keine zweite Abbuchung\"); return; }' ' fs.appendFileSync(LOG, id + \"\n\");' '}' > stapel1.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Die fortsetzbare Arbeit schreiben, Teil 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const zustand = laden();' 'console.log(\"Bisher fertig: \" + (zustand.fertig.join(\",\") || \"nichts\") + \". Unterbrochen bei: \" + zustand.gestartet);' 'for (const id of bestellungen) {' ' if (zustand.fertig.indexOf(id) >= 0) { console.log(id + \": übersprungen, schon fertig\"); continue; }' ' zustand.gestartet = id;' ' speichern(zustand);' ' abbuchen(id);' ' if (id === absturzBei) { console.log(\"Absturz bei der Arbeit an \" + id); process.exit(1); }' ' zustand.fertig.push(id);' ' zustand.gestartet = null;' ' speichern(zustand);' ' console.log(id + \": fertig\");' '}' 'console.log(\"Abgeschlossen. Abbuchungen: \" + fs.readFileSync(LOG, \"utf8\").trim().split(\"\n\").length);' >> stapel1.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Neu starten und bei B3 abstürzen
docker exec -w /home/node/project agent sh -c "rm -rf demo; node stapel1.js B3"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Noch einmal starten und fortsetzen
docker exec -w /home/node/project agent node stapel1.jsHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Eine mögliche Ausgabe
| Lauf | Was er zeigt |
|---|---|
| Erster | B1 fertig, B2 fertig, dann Absturz bei der Arbeit an B3 |
| Zweiter | Unterbrochen bei B3, B1 und B2 übersprungen |
| B3 im zweiten Lauf | schon abgebucht, keine zweite Abbuchung, dann fertig |
| Letzte Zeile | Abgeschlossen. Abbuchungen: 5, eine pro Bestellung |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Jeden Schritt wiederholbar machen
Ein Schritt ist idempotent, wenn zweimaliges Ausführen die Wirkung einmaligen Ausführens hat. Geben Sie jeder Wirkung einen Schlüssel, etwa die Bestellnummer. Prüfen Sie vor dem Handeln, ob der Schlüssel schon benutzt wurde.
Erlaubt es ein externer Dienst, senden Sie den Schlüssel mit der Anfrage, damit der Dienst eine Wiederholung ablehnen kann.
Ein häufiger Fehler
Warnung
Viele glauben, ein Prüfpunkt mache einen Neuversuch sicher. Ein Prüfpunkt hält nur fest, was fertig wurde. Ein Schritt, der nach seiner Wirkung abbricht, läuft erneut, also muss der Schritt wiederholbar sein. Nutzen Sie beides: einen Vermerk und einen idempotenten Schritt.