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

Code before:
where
    EK: KvEngine,
    ER: RaftEngine,
{
    fsm: &'a mut PeerFsm<EK, ER>,
    ctx: &'a mut PollContext<EK, ER, T>,
}

impl<'a, EK, ER, T: Transport> PeerFsmDelegate<'a, EK, ER, T>
where
    EK: KvEngine,
    ER: RaftEngine,
{
    pub fn new(
        fsm: &'a mut PeerFsm<EK, ER>,
        ctx: &'a mut PollContext<EK, ER, T>,
    ) -> PeerFsmDelegate<'a, EK, ER, T> {
        PeerFsmDelegate { fsm, ctx }
    }

    pub fn handle_msgs(&mut self, msgs: &mut Vec<PeerMsg<EK>>) {
        let timer = SlowTimer::from_millis(100);
        let count = msgs.len();
        #[allow(const_evaluatable_unchecked)]
        let mut distribution = [0; PeerMsg::<EK>::COUNT];
        let detail = msgs.get(0).map_or("".to_string(), |m| format!("{:?}", m));
        for m in msgs.drain(..) {
            distribution[m.discriminant()] += 1;
            match m {
                PeerMsg::RaftMessage(msg, sent_time) => {
                    if let Some(sent_time) = sent_time {
                        let wait_time = sent_time.saturating_elapsed().as_secs_f64();
                        self.ctx.raft_metrics.process_wait_time.observe(wait_time);
                    }

                    if !self.ctx.coprocessor_host.on_raft_message(&msg.msg) {
                        continue;
                    }

                    if let Err(e) = self.on_raft_message(msg) {
                        error!(%e;
                            "handle raft message err";
                            "region_id" => self.fsm.region_id(),
                            "peer_id" => self.fsm.peer_id(),
                        );
                    }
                }
                PeerMsg::RaftCommand(cmd) => {
                    let propose_time = cmd.send_time.saturating_elapsed();
                    self.ctx
                        .raft_metrics

Review comment (performance):
Just one concern is that the performance.

With this pr, each `msgs[0]` will be checked and formatted with string for the later logging by `slow_log!`. If there exists numerous peers in this node, the formatting cost of `msgs[0]` might be significant.

Code after:
where
    EK: KvEngine,
    ER: RaftEngine,
{
    fsm: &'a mut PeerFsm<EK, ER>,
    ctx: &'a mut PollContext<EK, ER, T>,
}

impl<'a, EK, ER, T: Transport> PeerFsmDelegate<'a, EK, ER, T>
where
    EK: KvEngine,
    ER: RaftEngine,
{
    pub fn new(
        fsm: &'a mut PeerFsm<EK, ER>,
        ctx: &'a mut PollContext<EK, ER, T>,
    ) -> PeerFsmDelegate<'a, EK, ER, T> {
        PeerFsmDelegate { fsm, ctx }
    }

    pub fn handle_msgs(&mut self, msgs: &mut Vec<PeerMsg<EK>>) {
        let timer = SlowTimer::from_millis(100);
        let count = msgs.len();
        #[allow(const_evaluatable_unchecked)]
        let mut distribution = [0; PeerMsg::<EK>::COUNT];
        // As the detail of one msg is not very useful when handling multiple messages,
        // only format the msg detail in slow log when there is only one message.
        let detail = if msgs.len() == 1 {
            msgs.first().map(|m| format!("{:?}", m))
        } else {
            None
        };

        for m in msgs.drain(..) {
            distribution[m.discriminant()] += 1;
            match m {
                PeerMsg::RaftMessage(msg, sent_time) => {
                    if let Some(sent_time) = sent_time {
                        let wait_time = sent_time.saturating_elapsed().as_secs_f64();
                        self.ctx.raft_metrics.process_wait_time.observe(wait_time);
                    }

                    if !self.ctx.coprocessor_host.on_raft_message(&msg.msg) {
                        continue;
                    }

                    if let Err(e) = self.on_raft_message(msg) {
                        error!(%e;
                            "handle raft message err";
                            "region_id" => self.fsm.region_id(),
                            "peer_id" => self.fsm.peer_id(),