@@ -1545,12 +1545,43 @@ void RaftPart::processAppendLogRequest(const cpp2::AppendLogRequest& req,
1545
1545
// previously in fact. There are two choise: ask leader to send logs after committedLogId_ or
1546
1546
// just do nothing.
1547
1547
if (req.get_last_log_id_sent () < committedLogId_ ||
1548
- wal_->lastLogId () < req.get_last_log_id_sent () ||
1549
- wal_->getLogTerm (req.get_last_log_id_sent ()) != req.get_last_log_term_sent ()) {
1548
+ wal_->lastLogId () < req.get_last_log_id_sent ()) {
1549
+ // case 1 and case 2
1550
+ resp.last_matched_log_id_ref () = committedLogId_;
1551
+ resp.last_matched_log_term () = committedLogTerm_;
1552
+ resp.error_code () = nebula::cpp2::ErrorCode::E_RAFT_LOG_GAP;
1553
+ return ;
1554
+ }
1555
+ auto prevLogTerm = wal_->getLogTerm (req.get_last_log_id_sent ());
1556
+ if (UNLIKELY (prevLogTerm == FileBasedWal::INVALID_TERM)) {
1557
+ /*
1558
+ At this point, the condition below established:
1559
+ committedLogId <= req.get_last_log_id_sent() <= wal_->lastLogId()
1560
+
1561
+ When INVALID_TERM is returned, we failed to find the log of req.get_last_log_id_sent()
1562
+ in wal. This usually happens the node has received a snapshot recently, so the wal is
1563
+ absent.
1564
+ */
1565
+ if (req.get_last_log_id_sent () == committedLogId_ &&
1566
+ req.get_last_log_term_sent () == committedLogTerm_) {
1567
+ // Logs are matched of at log index of committedLogId_, and we could check remaing wal if
1568
+ // there are any.
1569
+ // The first log of wal must be or committedLogId_ + 1, it can't be 0 (no wal) as well
1570
+ // because it has been checked by case 2
1571
+ DCHECK (wal_->firstLogId () == committedLogId_ + 1 );
1572
+ } else {
1573
+ // case 3: checked by committedLogId_ and committedLogTerm_
1574
+ // When log is not matched, we just return committedLogId_ and committedLogTerm_ instead
1575
+ resp.last_matched_log_id_ref () = committedLogId_;
1576
+ resp.last_matched_log_term () = committedLogTerm_;
1577
+ resp.error_code () = nebula::cpp2::ErrorCode::E_RAFT_LOG_GAP;
1578
+ return ;
1579
+ }
1580
+ } else if (prevLogTerm != req.get_last_log_term_sent ()) {
1581
+ // case 3
1550
1582
resp.last_matched_log_id_ref () = committedLogId_;
1551
1583
resp.last_matched_log_term () = committedLogTerm_;
1552
1584
resp.error_code () = nebula::cpp2::ErrorCode::E_RAFT_LOG_GAP;
1553
- // lastMatchedLogId is committedLogId_
1554
1585
return ;
1555
1586
}
1556
1587
0 commit comments