Append new entries from a leader's AppendEntries RPC. Handles conflict detection per Raft paper §5.3: - If an existing entry conflicts with a new one (same index, different terms), delete the existing entry and all that follow it. - Append any new entries not already in the log.
(&mut self, _prev_index: u64, entries: &[LogEntry])
| 101 | /// terms), delete the existing entry and all that follow it. |
| 102 | /// - Append any new entries not already in the log. |
| 103 | pub fn append_entries(&mut self, _prev_index: u64, entries: &[LogEntry]) -> Result<()> { |
| 104 | for entry in entries { |
| 105 | if let Some(existing) = self.entry_at(entry.index) { |
| 106 | if existing.term != entry.term { |
| 107 | // Conflict: truncate from this index onward. |
| 108 | self.truncate_from(entry.index); |
| 109 | self.entries.push(entry.clone()); |
| 110 | } |
| 111 | // Same term = already present, skip. |
| 112 | } else { |
| 113 | self.entries.push(entry.clone()); |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | // Persist. |
| 118 | if !entries.is_empty() { |
| 119 | self.storage.append(entries)?; |
| 120 | } |
| 121 | Ok(()) |
| 122 | } |
| 123 | |
| 124 | /// Append a single entry proposed by the leader. |
| 125 | pub fn append(&mut self, entry: LogEntry) -> Result<()> { |