Repository: tikv/tikv
File: components/raftstore/src/store/peer.rs (Rust)

Code before:
                .get_peers()
                .iter()
                .find(|p| p.get_id() == *peer_id)
                .unwrap();
            // Learners like TiFlash are ignored, because they may be tombstoned in earlier
            // stage of the unsafe recovery process, so that forced leader
            // cannot append logs to them.
            if failed_stores.contains(&peer.get_store_id()) || peer.get_role() == PeerRole::Learner
            {
                continue;
            }
            if replicated_idx > p.matched {
                replicated_idx = p.matched;
            }
        }

        if self.raft_group.store().term(replicated_idx).unwrap_or(0) < self.term() {
            // do not commit logs of previous term directly
            return false;
        }

        self.raft_group.raft.raft_log.committed =
            std::cmp::max(self.raft_group.raft.raft_log.committed, replicated_idx);
        true
    }

    pub fn check_stale_state<T>(&mut self, ctx: &mut PollContext<EK, ER, T>) -> StaleState {
        if self.is_leader() {
            // Leaders always have valid state.
            //
            // We update the leader_missing_time in the `fn step`. However one peer region
            // does not send any raft messages, so we have to check and update it before
            // reporting stale states.
            self.leader_missing_time = None;
            return StaleState::Valid;
        }
        // Updates the `leader_missing_time` according to the current state.
        //
        // If we are checking this it means we suspect the leader might be missing.
        // Mark down the time when we are called, so we can check later if it's been
        // longer than it should be.
        match self.leader_missing_time {
            None => {
                self.leader_missing_time = Instant::now().into();
                StaleState::Valid
            }
            Some(instant)
                if instant.saturating_elapsed() >= ctx.cfg.max_leader_missing_duration.0 =>
            {
                // Resets the `leader_missing_time` to avoid sending the same tasks to
                // PD worker continuously during the leader missing timeout.

Review comment (suggestion):
we can't simply pass learner, considering the case where all left peers are learners. We should check whether it is on tiflash by checking the label. I think you can get the store from `StoreGroup`

Code after:
            }
        }
        if self.down_peer_ids.contains(&peer_id) {
            return true;
        }
        false
    }

    pub fn maybe_force_forward_commit_index(&mut self) -> bool {
        let failed_stores = match &self.force_leader {
            Some(ForceLeaderState::ForceLeader { failed_stores, .. }) => failed_stores,
            _ => unreachable!(),
        };

        let region = self.region();
        let mut replicated_idx = self.raft_group.raft.raft_log.persisted;
        for (peer_id, p) in self.raft_group.raft.prs().iter() {
            let peer = region
                .get_peers()
                .iter()
                .find(|p| p.get_id() == *peer_id)
                .unwrap();
            // Learners like TiFlash are ignored, because they may be tombstoned in earlier
            // stage of the unsafe recovery process, so that forced leader
            // cannot append logs to them.
            if failed_stores.contains(&peer.get_store_id()) || peer.get_role() == PeerRole::Learner
            {
                continue;
            }
            if replicated_idx > p.matched {
                replicated_idx = p.matched;
            }
        }

        if self.raft_group.store().term(replicated_idx).unwrap_or(0) < self.term() {
            // do not commit logs of previous term directly
            return false;
        }

        self.raft_group.raft.raft_log.committed =
            std::cmp::max(self.raft_group.raft.raft_log.committed, replicated_idx);
        true
    }

    pub fn check_stale_state<T>(&mut self, ctx: &mut PollContext<EK, ER, T>) -> StaleState {
        if self.is_leader() {
            // Leaders always have valid state.
            //
            // We update the leader_missing_time in the `fn step`. However one peer region
            // does not send any raft messages, so we have to check and update it before
            // reporting stale states.