From 05dcc60cbce9d6fce29443bb80dceeb6c74d47b1 Mon Sep 17 00:00:00 2001
From: Yaroslav Dynnikov <yaroslav.dynnikov@gmail.com>
Date: Wed, 26 Oct 2022 01:55:21 +0300
Subject: [PATCH] refactor: squeeze raft log bootstrapping

This commit slignly changes the order of entries in the raft log:
ConfChange now comes at the first place before other Ops, but that's ok.
---
 src/main.rs | 107 +++++++++++++++++++++-------------------------------
 1 file changed, 43 insertions(+), 64 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index 0cb3d23b7f..2dddfd4307 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -701,77 +701,50 @@ fn start_boot(args: &args::Run) {
 
     let mut storage = init_common(args, &cfg);
 
-    start_transaction(|| -> Result<(), TntError> {
-        let cs = raft::ConfState {
-            voters: vec![raft_id],
-            ..Default::default()
-        };
+    let cs = raft::ConfState {
+        voters: vec![raft_id],
+        ..Default::default()
+    };
 
+    let init_entries: Vec<raft::Entry> = {
         let mut lc = LogicalClock::new(raft_id, 0);
-
         let mut init_entries = Vec::new();
-        init_entries.push({
-            let ctx = traft::EntryContextNormal {
-                op: traft::Op::PersistPeer { peer },
-                lc,
-            };
-            let e = traft::Entry {
-                entry_type: raft::EntryType::EntryNormal,
-                index: (init_entries.len() + 1) as _,
-                term: 1,
-                data: vec![],
-                context: Some(traft::EntryContext::Normal(ctx)),
-            };
 
-            raft::Entry::try_from(e).unwrap()
-        });
+        let mut init_entries_push_op = |op| {
+            lc.inc();
 
-        lc.inc();
-        init_entries.push({
-            let ctx = traft::EntryContextNormal {
-                op: traft::OpDML::insert(
-                    ClusterSpace::State,
-                    &(StateKey::ReplicationFactor, args.init_replication_factor),
-                )
-                .expect("cannot fail")
-                .into(),
-                lc,
-            };
+            let ctx = traft::EntryContextNormal { op, lc };
             let e = traft::Entry {
                 entry_type: raft::EntryType::EntryNormal,
                 index: (init_entries.len() + 1) as _,
-                term: 1,
+                term: traft::INIT_RAFT_TERM,
                 data: vec![],
                 context: Some(traft::EntryContext::Normal(ctx)),
             };
 
-            raft::Entry::try_from(e).unwrap()
-        });
-
-        lc.inc();
-        init_entries.push({
-            let ctx = traft::EntryContextNormal {
-                op: traft::OpDML::insert(
-                    ClusterSpace::State,
-                    &(StateKey::ReplicasetWeights, ReplicasetWeights::new()),
-                )
-                .expect("cannot fail")
-                .into(),
-                lc,
-            };
-            let e = traft::Entry {
-                entry_type: raft::EntryType::EntryNormal,
-                index: (init_entries.len() + 1) as _,
-                term: 1,
-                data: vec![],
-                context: Some(traft::EntryContext::Normal(ctx)),
-            };
+            init_entries.push(raft::Entry::try_from(e).unwrap());
+        };
 
-            raft::Entry::try_from(e).unwrap()
-        });
+        init_entries_push_op(traft::Op::PersistPeer { peer });
+        init_entries_push_op(
+            traft::OpDML::insert(
+                ClusterSpace::State,
+                &(StateKey::ReplicationFactor, args.init_replication_factor),
+            )
+            .expect("cannot fail")
+            .into(),
+        );
+        init_entries_push_op(
+            traft::OpDML::insert(
+                ClusterSpace::State,
+                &(StateKey::ReplicasetWeights, ReplicasetWeights::new()),
+            )
+            .expect("cannot fail")
+            .into(),
+        );
 
         init_entries.push({
-            let conf_change = raft::ConfChange {
+            let cc = raft::ConfChange {
                 change_type: raft::ConfChangeType::AddNode,
                 node_id: raft_id,
                 ..Default::default()
@@ -779,23 +752,29 @@ fn start_boot(args: &args::Run) {
             let e = traft::Entry {
                 entry_type: raft::EntryType::EntryConfChange,
                 index: (init_entries.len() + 1) as _,
-                term: 1,
-                data: conf_change.write_to_bytes().unwrap(),
+                term: traft::INIT_RAFT_TERM,
+                data: cc.write_to_bytes().unwrap(),
                 context: None,
             };
 
             raft::Entry::try_from(e).unwrap()
         });
 
-        storage.raft.persist_conf_state(&cs).unwrap();
-        storage.raft.persist_entries(&init_entries).unwrap();
+        init_entries
+    };
+
+    let hs = raft::HardState {
+        term: traft::INIT_RAFT_TERM,
+        commit: init_entries.len() as _,
+        ..Default::default()
+    };
+
+    start_transaction(|| -> Result<(), TntError> {
         storage.raft.persist_raft_id(raft_id).unwrap();
         storage.raft.persist_instance_id(&instance_id).unwrap();
         storage.raft.persist_cluster_id(&args.cluster_id).unwrap();
-
-        let mut hs = raft::HardState::default();
-        hs.set_commit(init_entries.len() as _);
-        hs.set_term(traft::INIT_RAFT_TERM);
+        storage.raft.persist_entries(&init_entries).unwrap();
+        storage.raft.persist_conf_state(&cs).unwrap();
         storage.raft.persist_hard_state(&hs).unwrap();
         Ok(())
     })
-- 
GitLab