
# Atomarnost in obnova

`AtomicFilesystem::write_atomic()` zapiše v začasno datoteko, izprazni medpomnilnik in
izvede fsync na njenem ročaju, jo preimenuje čez ciljno pot ter poskusi izvesti fsync
nadrejene mape. Ob neuspešnem zapisovanju se začasna datoteka odstrani.

Instance zapisovalne shrambe pod `.storh/writers/` registrirajo oznako za posamezen proces
in jo ob pravilnem zaustavljanju odstranijo. Ob odprtju shrambe se oznake preverijo: če so vsi lastniški procesi dejavni (ali oznak ni), je odpiranje konstantno hitro; oznaka, katere lastniški proces je končal, pomeni, da se je zapisovalnik sesul, zato se ob odprtju preišče zbirka osirotelih začasnih datotek in odstrani zastarela oznaka. `repair()` vedno izvede pregled.

Popravilo DocStore poškodovane ali odrezane datoteke zapisov prestavi v karanteno pod `.storh/corrupt/` in iz preostalih veljavnih zapisov znova zgradi sekundarne indekse. Preverjanje DocStore primerja tudi datoteke indeksov s celotnim pregledom zapisov, tako da so manjkajoči ali zastareli vnosi v indeksih zaznani, še preden jih je mogoče obravnavati kot pravilne.

Mehanizmi, ki zapisujejo samo na konec, izpraznijo medpomnilnike in izvedejo fsync nad ročaji dnevniških datotek, preden dogodke obravnavajo kot potrjene v pomnilniku. Trajnost ob izpadu napajanja je še vedno odvisna od tega, ali osnovni datotečni sistem in možnosti priklopa upoštevajo sinhronizacijo datotek in map.

Segmentirani dnevnik zapiše vsako vrstico takole:

```text
<byte-length>\t<xxh32>\t<json>\n
```

Pri branju se preverita dolžina v bajtih in kontrolna vsota. Obnovitev pregleda vsak segment in datoteko odreže pri zadnji popolni veljavni vrstici, s čimer odstrani nepopolne zapise na koncu. Preverjanje primerja aktivni izpeljani indeks stanja z neodvisnim predvajanjem segmentov, tako da se zunanje spremenjeno ali zastarelo stanje zazna, preden ga popravilo znova zgradi.

Preverjanje čakalne vrste dekodira vsak trajni dogodek čakalne vrste in primerja trenutno stanje čakajočih, obdelanih, dokončanih opravil, njihovih vsebin in vrstnega reda zahtevkov z neodvisnim predvajanjem dnevnika. Popravilo znova zgradi stanje iz `queue.log` in odreže nepopolne dogodke na koncu. Med pridobivanjem opravil in zaključevanjem ob zaklepanju čakalne vrste pride do sinhronizacije s trajnim dnevnikom, zato več delovnih procesov ne prevzame istega čakajočega opravila.

Zgoščevanje zapiše nove datoteke segmentov `compact-*` in nato posodobi manifest.
Če se proces konča pred zamenjavo manifesta, se ob ponovnem odprtju odstranijo nepovezani rezultati zgoščevanja in nadaljuje delo s starim manifestom. Po dokončanem zgoščevanju stari zapečateni segmenti namerno ostanejo, da bralci, ki jih že berejo, ostanejo neovirani.
