@@ -1566,12 +1566,42 @@ void RaftPart::processAppendLogRequest(const cpp2::AppendLogRequest& req,
1566
1566
// previously in fact. There are two choise: ask leader to send logs after committedLogId_ or
1567
1567
// just do nothing.
1568
1568
if (req.get_last_log_id_sent () < committedLogId_ ||
1569
- wal_->lastLogId () < req.get_last_log_id_sent () ||
1570
- wal_->getLogTerm (req.get_last_log_id_sent ()) != req.get_last_log_term_sent ()) {
1569
+ wal_->lastLogId () < req.get_last_log_id_sent ()) {
1570
+ // case 1 and case 2
1571
+ resp.last_matched_log_id_ref () = committedLogId_;
1572
+ resp.last_matched_log_term () = committedLogTerm_;
1573
+ resp.error_code () = nebula::cpp2::ErrorCode::E_RAFT_LOG_GAP;
1574
+ return ;
1575
+ }
1576
+ auto prevLogTerm = wal_->getLogTerm (req.get_last_log_id_sent ());
1577
+ if (UNLIKELY (prevLogTerm == FileBasedWal::INVALID_TERM)) {
1578
+ /*
1579
+ At this point, the condition below established:
1580
+ committedLogId <= req.get_last_log_id_sent() <= wal_->lastLogId()
1581
+
1582
+ When INVALID_TERM is returned, we failed to find the log of req.get_last_log_id_sent()
1583
+ in wal. This usually happens the node has received a snapshot recently.
1584
+ */
1585
+ if (req.get_last_log_id_sent () == committedLogId_ &&
1586
+ req.get_last_log_term_sent () == committedLogTerm_) {
1587
+ // Logs are matched of at log index of committedLogId_, and we could check remaing wal if
1588
+ // there are any.
1589
+ // The first log of wal must be committedLogId_ + 1, it can't be 0 (no wal) as well
1590
+ // because it has been checked by case 2
1591
+ DCHECK (wal_->firstLogId () == committedLogId_ + 1 );
1592
+ } else {
1593
+ // case 3: checked by committedLogId_ and committedLogTerm_
1594
+ // When log is not matched, we just return committedLogId_ and committedLogTerm_ instead
1595
+ resp.last_matched_log_id_ref () = committedLogId_;
1596
+ resp.last_matched_log_term () = committedLogTerm_;
1597
+ resp.error_code () = nebula::cpp2::ErrorCode::E_RAFT_LOG_GAP;
1598
+ return ;
1599
+ }
1600
+ } else if (prevLogTerm != req.get_last_log_term_sent ()) {
1601
+ // case 3
1571
1602
resp.last_matched_log_id_ref () = committedLogId_;
1572
1603
resp.last_matched_log_term () = committedLogTerm_;
1573
1604
resp.error_code () = nebula::cpp2::ErrorCode::E_RAFT_LOG_GAP;
1574
- // lastMatchedLogId is committedLogId_
1575
1605
return ;
1576
1606
}
1577
1607
0 commit comments