MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / do_tick

Method do_tick

nodedb-cluster/src/raft_loop/tick.rs:39–333  ·  view source on GitHub ↗

Execute a single tick: drive Raft, dispatch outbound messages, apply commits, promote caught-up learners.

(&self)

Source from the content-addressed store, hash-verified

37 /// Execute a single tick: drive Raft, dispatch outbound messages,
38 /// apply commits, promote caught-up learners.
39 pub(super) fn do_tick(&self) {
40 // Tick under lock and extract Ready.
41 let ready = {
42 let mut mr = self.multi_raft.lock().unwrap_or_else(|p| p.into_inner());
43 mr.tick()
44 };
45
46 // Dispatch outgoing messages and persist log/HardState first (even if
47 // ready looks "empty" we still want to run the learner-promotion step
48 // each tick so a just-caught-up learner is promoted promptly).
49 if !ready.is_empty() {
50 let mut ae_batches: BatchMap<u64, Vec<(u64, nodedb_raft::AppendEntriesRequest)>> =
51 BatchMap::new();
52 let mut vote_batches: BatchMap<u64, Vec<(u64, nodedb_raft::RequestVoteRequest)>> =
53 BatchMap::new();
54
55 for (group_id, group_ready) in &ready.groups {
56 for (peer, req) in &group_ready.messages {
57 ae_batches
58 .entry(*peer)
59 .or_default()
60 .push((*group_id, req.clone()));
61 }
62 for (peer, req) in &group_ready.vote_requests {
63 vote_batches
64 .entry(*peer)
65 .or_default()
66 .push((*group_id, req.clone()));
67 }
68 }
69
70 // Dispatch batched AppendEntries — one task per peer.
71 //
72 // Each detached task subscribes to the shutdown watch
73 // and wraps its RPC awaits in `tokio::select!` so a
74 // `RaftLoop::begin_shutdown` signal (or the `run` loop
75 // propagating an external shutdown) cancels the
76 // in-flight QUIC call at the next await point. This
77 // is what lets graceful shutdown drop the
78 // `Arc<Mutex<MultiRaft>>` clone promptly and release
79 // per-group redb locks for an in-process restart.
80 for (peer, messages) in ae_batches {
81 let transport = self.transport.clone();
82 let mr = self.multi_raft.clone();
83 let mut shutdown_rx = self.shutdown_watch.subscribe();
84 tokio::spawn(async move {
85 if *shutdown_rx.borrow() {
86 return;
87 }
88 for (group_id, req) in messages {
89 tokio::select! {
90 biased;
91 _ = shutdown_rx.changed() => return,
92 rpc = transport.append_entries(peer, req) => {
93 match rpc {
94 Ok(resp) => {
95 let mut mr =
96 mr.lock().unwrap_or_else(|p| p.into_inner());

Calls 15

bump_local_cluster_epochFunction · 0.85
lockMethod · 0.80
entryMethod · 0.80
borrowMethod · 0.80
apply_conf_changeMethod · 0.80
collectMethod · 0.80
group_role_is_leaderMethod · 0.80
spawnFunction · 0.50
tickMethod · 0.45

Tested by

no test coverage detected