Schreibverfahren: kein Datenverlust bei Absturz #19

Open
opened 2026-08-28 09:21:16 +00:00 by RDietermann · 0 comments
Owner

Part of #16

Question

Wie genau wird eine Notiz auf die Platte geschrieben, sodass ein Absturz sie nicht zerstört?

Ein direkter fs::write auf die Zieldatei kürzt sie zuerst und schreibt dann. Bricht der Vorgang mittendrin ab — Stromausfall, Absturz, volle Platte —, ist die Notiz nicht mehr die alte und noch nicht die neue, sondern zerstört. Genau das Szenario, gegen das „deine Notizen sind gewöhnliche Dateien" schützen soll.

Zu entscheiden:

  • Schreiben über temporäre Datei plus rename? Wo liegt die temporäre Datei — neben der Notiz oder im Systemtemp? (Ein rename über Laufwerksgrenzen hinweg ist kein atomarer Vorgang.)
  • Wird die temporäre Datei im Baum sichtbar? Sie muss dort verschwinden, ohne dass die Punkt-Regel dafür aufgeweicht wird.
  • Braucht es ein sync_all vor dem Umbenennen, oder ist das übertrieben für eine Notiz-App?
  • Was passiert mit den Dateirechten und dem Änderungsdatum der Zieldatei?
  • Was bleibt liegen, wenn der Vorgang zwischen Schreiben und Umbenennen abbricht — und wer räumt das auf?

Zielgröße: die Schreibfunktion in Pseudocode, plus die Antwort, was nach einem Absturz auf der Platte liegt.


Nachtrag nach #22. Die Recherche entkräftet den Einwand aus der Beratungsrunde und liefert dabei belegte Fakten, die dieses Ticket direkt betreffen.

1. Historie stellt genau eine Anforderung: eine einzige Schreibstelle. „Temporäre Datei, dann umbenennen" schließt Historie nicht aus, sondern macht sie erst billig — die Vorfassung liegt zum Zeitpunkt des Umbenennens noch unversehrt da. Teuer wird es nur, wenn nach einem halben Jahr fünf Stellen im Code Notizen schreiben. Das kostet heute nichts, weil es noch keine Schreibstelle gibt.

2. Microsoft empfiehlt für genau diesen Fall ReplaceFile, nicht MoveFileEx. Aus der TxF-Deprecation-Doku, Abschnitt „Applications updating a single file with document-like data".

3. Temp+rename verliert Metadaten — und das ist belegt, nicht vermutet: Die ReplaceFileW-Remarks führen als Vorteil auf, dass die Funktion Erstellungszeit, DACLs, Verschlüsselung, Komprimierung und benannte Streams erhält, was per Kontrast zeigt, dass ein nacktes Umbenennen sie verliert. Die File ID ändert sich sogar bei ReplaceFile. Kein untersuchtes Rust-Crate (tempfile, atomicwrites, atomic-write-file) benutzt ReplaceFile.

→ Folge, die hier zu entscheiden ist: Ein „erstellt am" gehört damit ins Frontmatter der .md, nicht ins Dateisystem. Das berührt auch #23 (Anlegen).

4. Das realistischste Fehlerbild ist ERROR_SHARING_VIOLATION, wenn Defender oder ein Sync-Client die Zieldatei ohne FILE_SHARE_DELETE offen hält. tempfile::NamedTempFile::persist gibt die temporäre Datei im PersistError zurück — gebaut genau für den Wiederholungsfall. Ebenfalls belegt: persist synchronisiert weder Inhalt noch Verzeichnis, die sync_all-Frage bleibt also eine eigene.

5. Die temporäre Datei muss im selben Verzeichnis liegen — fs::rename scheitert über Volume-Grenzen. Damit ist die Frage im Ticket beantwortet: nicht ins Systemtemp. Offen bleibt, wie sie aus dem Baum ferngehalten wird, ohne die Punkt-Regel aufzuweichen.

Part of #16 ## Question Wie genau wird eine Notiz auf die Platte geschrieben, sodass ein Absturz sie nicht zerstört? Ein direkter `fs::write` auf die Zieldatei kürzt sie zuerst und schreibt dann. Bricht der Vorgang mittendrin ab — Stromausfall, Absturz, volle Platte —, ist die Notiz nicht mehr die alte und noch nicht die neue, sondern zerstört. Genau das Szenario, gegen das „deine Notizen sind gewöhnliche Dateien" schützen soll. Zu entscheiden: - Schreiben über temporäre Datei plus `rename`? Wo liegt die temporäre Datei — neben der Notiz oder im Systemtemp? (Ein `rename` über Laufwerksgrenzen hinweg ist kein atomarer Vorgang.) - Wird die temporäre Datei im Baum sichtbar? Sie muss dort verschwinden, ohne dass die Punkt-Regel dafür aufgeweicht wird. - Braucht es ein `sync_all` vor dem Umbenennen, oder ist das übertrieben für eine Notiz-App? - Was passiert mit den Dateirechten und dem Änderungsdatum der Zieldatei? - Was bleibt liegen, wenn der Vorgang zwischen Schreiben und Umbenennen abbricht — und wer räumt das auf? Zielgröße: die Schreibfunktion in Pseudocode, plus die Antwort, was nach einem Absturz auf der Platte liegt. --- **Nachtrag nach #22.** Die Recherche entkräftet den Einwand aus der Beratungsrunde und liefert dabei belegte Fakten, die dieses Ticket direkt betreffen. **1. Historie stellt genau eine Anforderung: eine einzige Schreibstelle.** „Temporäre Datei, dann umbenennen" schließt Historie nicht aus, sondern macht sie erst billig — die Vorfassung liegt zum Zeitpunkt des Umbenennens noch unversehrt da. Teuer wird es nur, wenn nach einem halben Jahr fünf Stellen im Code Notizen schreiben. Das kostet heute nichts, weil es noch keine Schreibstelle gibt. **2. Microsoft empfiehlt für genau diesen Fall `ReplaceFile`, nicht `MoveFileEx`.** Aus der TxF-Deprecation-Doku, Abschnitt „Applications updating a single file with document-like data". **3. Temp+rename verliert Metadaten** — und das ist belegt, nicht vermutet: Die `ReplaceFileW`-Remarks führen als *Vorteil* auf, dass die Funktion Erstellungszeit, DACLs, Verschlüsselung, Komprimierung und benannte Streams erhält, was per Kontrast zeigt, dass ein nacktes Umbenennen sie verliert. Die File ID ändert sich sogar bei `ReplaceFile`. Kein untersuchtes Rust-Crate (`tempfile`, `atomicwrites`, `atomic-write-file`) benutzt `ReplaceFile`. → **Folge, die hier zu entscheiden ist:** Ein „erstellt am" gehört damit ins Frontmatter der `.md`, nicht ins Dateisystem. Das berührt auch #23 (Anlegen). **4. Das realistischste Fehlerbild ist `ERROR_SHARING_VIOLATION`**, wenn Defender oder ein Sync-Client die Zieldatei ohne `FILE_SHARE_DELETE` offen hält. `tempfile::NamedTempFile::persist` gibt die temporäre Datei im `PersistError` zurück — gebaut genau für den Wiederholungsfall. Ebenfalls belegt: `persist` synchronisiert weder Inhalt noch Verzeichnis, die `sync_all`-Frage bleibt also eine eigene. **5. Die temporäre Datei muss im selben Verzeichnis liegen** — `fs::rename` scheitert über Volume-Grenzen. Damit ist die Frage im Ticket beantwortet: nicht ins Systemtemp. Offen bleibt, wie sie aus dem Baum ferngehalten wird, ohne die Punkt-Regel aufzuweichen.
RDietermann added the wayfinder:grilling label 2026-08-28 09:21:16 +00:00
RDietermann added a new dependency 2026-08-28 09:24:09 +00:00
Sign in to join this conversation.