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

Code before:
        ctx: &mut PollContext<EK, ER, T>,
        mut index: u64,
        peer: &metapb::Peer,
    ) -> Option<&'static str> {
        let peer_id = peer.get_id();
        let status = self.raft_group.status();
        let progress = status.progress.unwrap();

        if !progress.conf().voters().contains(peer_id) {
            return Some("non voter");
        }

        for (id, pr) in progress.iter() {
            if pr.state == ProgressState::Snapshot {
                return Some("pending snapshot");
            }
            if *id == peer_id && index == 0 {
                // index will be zero if it's sent from an instance without
                // pre-transfer-leader feature. Set it to matched to make it
                // possible to transfer leader to an older version. It may be
                // useful during rolling restart.
                index = pr.matched;
            }
        }

        if self.raft_group.raft.has_pending_conf()
            || self.raft_group.raft.pending_conf_index > index
        {
            return Some("pending conf change");
        }

        let last_index = self.get_store().last_index();
        if last_index >= index + ctx.cfg.leader_transfer_max_log_lag {
            return Some("log gap");
        }
        None
    }

    fn read_local<T>(
        &mut self,
        ctx: &mut PollContext<EK, ER, T>,
        req: RaftCmdRequest,
        cb: Callback<EK::Snapshot>,
    ) {
        ctx.raft_metrics.propose.local_read.inc();
        cb.invoke_read(self.handle_read(ctx, req, false, Some(self.get_store().commit_index())))
    }

    pub fn pre_read_index(&self) -> Result<()> {
        fail_point!(
            "before_propose_readindex",

Review comment (suggestion):
```suggestion
                "transferee_applied_index" => index
```

We use the term "transferee" instead of "target".

Code after:

        for (id, pr) in progress.iter() {
            if pr.state == ProgressState::Snapshot {
                return Some("pending snapshot");
            }
            if *id == peer_id && index == 0 {
                // index will be zero if it's sent from an instance without
                // pre-transfer-leader feature. Set it to matched to make it
                // possible to transfer leader to an older version. It may be
                // useful during rolling restart.
                index = pr.matched;
            }
        }

        // It's safe to transfer leader to a target peer that has already applied the
        // configuration change, even if the current leader has not yet applied
        // it. For more details, refer to the issue at:
        // https://github.com/tikv/tikv/issues/17363#issuecomment-2404227253.
        if self.raft_group.raft.pending_conf_index > index {
            info!(
                "not ready to transfer leader, transferee has an unapplied conf change";
                "region_id" => self.region_id,
                "transferee_peer_id" => peer_id,
                "pending_conf_index" => self.raft_group.raft.pending_conf_index,
                "applied_index" => self.raft_group.raft.raft_log.applied,
                "transferee_applied_index" => index
            );
            return Some("pending conf change");
        }

        if self.raft_group.raft.has_pending_conf() {
            info!(
                "transfer leader with pending conf on current leader";
                "region_id" => self.region_id,
                "transferee_peer_id" => peer_id,
                "transferee_applied_index" => index,
                "pending_conf_index" => self.raft_group.raft.pending_conf_index,
                "last_index" => self.get_store().last_index(),
                "persist_index" => self.raft_group.raft.raft_log.persisted,
                "committed_index" => self.raft_group.raft.raft_log.committed,
                "applied_index" => self.raft_group.raft.raft_log.applied,
            );
        }

        let last_index = self.get_store().last_index();
        if last_index >= index + ctx.cfg.leader_transfer_max_log_lag {
            return Some("log gap");
        }
        None
    }