Co to znamená
Každý restart serveru je nový stream žurnálu, takže runtime kompaktují streamy, které jsou dlouho mrtvé. Compaction odebírá záznamy těchto streamů a nic, na co se ještě někdo spoléhá: platný nárok a otevřená relace se nikdy nedotknou; předávka, kterou nikdo nevzal, drží svůj stream den po retenci a ne déle, takže stroj, jehož každý běh něco předal, nemůže zaplnit kvótu mrtvými; stále nabízená předávka drží každého, kdo ji vzal, a revize drží každou odpověď, i když runtime toho, kdo vzal nebo odpověděl, přestal běžet. A runtime zkompaktovaný, zatímco spal — notebook po expiraci a patnáctiminutové retenci — je opět slyšet, když se probudí: jeho peery znovu stáhnou jeho stream od první události, takže nárok, který převzal před spánkem, tam opět platí a odmítne konfliktní.
Princip
Journal::compact (apps/majordomus-cli/src/mesh/journal.rs) zvažuje jen streamy, které mlčí déle než expirace plus retence. Z nich ponechá stream, který nabízí předávku, již fold uvádí bez příjemce, dokud jeho mlčení nepřekročí retenci o více než HANDOVER_RETENTION, a — až do pevného bodu — stream, který drží převzetí předávky nebo odpověď na review, jehož vlastní stream je ponechán. Kdo převzal a kdo odpověděl, čte mesh::state::fold, čtení, které ukazuje každý povrch. To, co odejde, zanechá náhrobek: dosaženou sekvenci, oznámenou, aby se neposílala znovu, a tep, při kterém byl stream naposledy slyšet. Pozdní událost zkompaktovaného streamu se vstřebá do náhrobku. Journal::merge_marks sejme náhrobek při ověřeném, důvěryhodném tepu, který je čerstvý a nad tepem náhrobku; značka streamu klesne na nic nedržené a peers jej pošlou znovu od první události. Supervizor serveru kompaktuje každých šedesát heartbeatů pomocí PEER_RETENTION a HANDOVER_RETENTION (apps/majordomus-cli/src/mesh/cooperation.rs).
Jak to vidět
test/run.sh 493_mesh_compaction_keeps_what_is_live
cargo test --manifest-path apps/majordomus-cli/Cargo.toml --test mesh_compaction
cargo test --manifest-path apps/majordomus-cli/Cargo.toml --lib mesh::journal
Případ spouští tests/mesh_compaction.rs: dva runtimy propojené skutečným podepsaným protokolem přes transport v rámci procesu, jeden zkompaktovaný, zatímco spí, a znovu celý vyslechnutý po probuzení, přebírající a recenzent, kteří se zastaví, zatímco publikující běží, a dva zastavení publikující, z nichž se ponechá jen ten, jehož předávku nikdo nepřevzal. Jednotkové testy žurnálu reprodukují každou vadu, kterou zaznamenal PR 588, a jeho property test compacting_a_crowded_node_changes_nothing_live platí nad náhodnými historiemi, které žádné živé tvrzení, otevřená relace, přebírající předávky ani odpověď na review nemění.
Co nepokrývá
Žádný black-box případ nedosáhne compaction v omezeném čase — server kompaktuje každých šedesát heartbeatů a mrtvý stream drží patnáct minut a deklarovat lze jen heartbeat a expiraci — takže důkazem jsou vlastní runtime knihovny, ne dva servery. Dva runtime mohou vypsat různé digesty, zatímco každý kompaktuje podle svého rozvrhu: jeden zapomněl ukončené záznamy mrtvého streamu, které druhý stále uvádí. Co je živé, se shoduje a značky se shodují. Žádost o revizi mrtvého runtime sama nic neudrží a odchází se svým streamem. Náhrobky se nepersistují: restartovanému runtime lze zkompaktovaný stream poslat znovu a později ho znovu zahodí.
Proč existuje
Kompakce je to, co brání stroji, který restartuje své servery, zaplnit kvótu, a mez, která zapomíná, co je živé, je horší než žádná mez: předávka, která vypadá nepřevzatá, se převezme dvakrát, revize, která se znovu otevře, se zodpoví dvakrát, a runtime, který se probudí neslyšen, drží nároky, které jeho peeři nevidí. PR 588 zaznamenal všechny tři; toto tvrzení je jejich uzavřením.