Try to advance `commit_index` based on the voter quorum only. Learners' `match_index` is tracked (so we know when they are caught up for promotion) but intentionally excluded from this calculation so adding a learner never weakens the commit quorum.
(&mut self)
| 321 | /// up for promotion) but intentionally excluded from this calculation |
| 322 | /// so adding a learner never weakens the commit quorum. |
| 323 | pub(super) fn try_advance_commit_index(&mut self) { |
| 324 | let leader = match &self.leader_state { |
| 325 | Some(ls) => ls, |
| 326 | None => return, |
| 327 | }; |
| 328 | |
| 329 | let last = self.log.last_index(); |
| 330 | for n in (self.volatile.commit_index + 1..=last).rev() { |
| 331 | let term_at_n = match self.log.term_at(n) { |
| 332 | Some(t) => t, |
| 333 | None => continue, |
| 334 | }; |
| 335 | |
| 336 | if term_at_n != self.hard_state.current_term { |
| 337 | continue; |
| 338 | } |
| 339 | |
| 340 | let mut count = 1u64; // self counts. |
| 341 | for &peer in &self.config.peers { |
| 342 | if leader.match_index_for(peer) >= n { |
| 343 | count += 1; |
| 344 | } |
| 345 | } |
| 346 | |
| 347 | if count as usize >= self.config.quorum() { |
| 348 | self.volatile.commit_index = n; |
| 349 | self.collect_committed_entries(); |
| 350 | break; |
| 351 | } |
| 352 | } |
| 353 | } |
| 354 | |
| 355 | pub(super) fn collect_committed_entries(&mut self) { |
| 356 | let from = self.volatile.last_applied + 1; |
no test coverage detected