pub(crate) fn switch_to_config(&mut self, cfg: tracker::Config, prs: ProgressMap) -> ConfState {
        self.prs.config = cfg;
        self.prs.progress = prs;
        info!("{} switched to configuration {}", self.id, self.prs.config);
        let cs = self.prs.config_state();
        let pr = self.prs.progress.get(&self.id);
        // Update
        self.is_learner = pr.is_some() && pr.as_ref().unwrap().is_learner;
        if (pr.is_none() || self.is_learner) && self.state == StateType::Leader {
            // This node is leader and was removed or demoted. We prevent demotions
            // at the time writing but hypothetically we handle them the same way as
            // removing the leader; stepping down into the next Term.
            //
            // TODO(tbg): step down (for sanity) and ask follower with largest Match
            // to TimeoutNow (to advoid interruption). This might still drop some
            // proposals but it's bette than nothing.
            //
            // TODO(tbg): test this branch. It is untested at the time of writing.
            return cs;
        }

        // The remaining steps only make sense if this node is the leader and there
        // are other nodes.
        if self.state != StateType::Leader || cs.get_voters().is_empty() {
            return cs;
        }

        if self.maybe_commit() {
            // If the configuration change means that more entries are committed now,
            // broadcast/append to everyone in the updated config.
            self.bcast_append();
        } else {
            // Otherwise, still probe the newly added replicas; there's no reason to
            // let them wait out a heartbeat interval (or the next incoming
            // proposal).
            // TODO:
            //
            self.prs.visit_nodes().iter_mut().for_each(|id| {
                self.maybe_send_append(*id, false);
            })
            //            self.prs.visit(|id, pr| {
            //                self.maybe_send_append(id, false);
            //            });
        }
        // If the leaderTransferee was removed or demoted, abort the leadership transfer.
        let t_ok = self.prs.config.voters.ids().contains(&self.lead_transferee);
        if !t_ok && self.lead_transferee != 0 {
            self.abort_leader_transferee();
        }
        cs
    }
// switch_to_config reconfigures this node to use the provided configuration. It
// updates the in-memory state and, when necessary, carries out additional
// actions such as reacting to the removal of nodes or changed quorum
// requirements.
//
// The inputs usually result from restoring a ConfState or apply a ConfState
switch_to_config reconfigures this node to use the provided configuration. It
updates the in-memory state and, when necessary, carries out additional
actions such as reacting to the removal of nodes or changed quorum
requirements.

The inputs usually result from restoring a ConfState or apply a ConfState
switch_to_config reconfigures this node to use the provided configuration . It updates the in - memory state and when necessary carries out additional actions such as reacting to the removal of nodes or changed quorum requirements . The inputs usually result from restoring a ConfState or apply a ConfState
pub(crate) fn switch_to_config(&mut self, cfg: tracker::Config, prs: ProgressMap) -> ConfState {
        self.prs.config = cfg;
        self.prs.progress = prs;
        info!("{} switched to configuration {}", self.id, self.prs.config);
        let cs = self.prs.config_state();
        let pr = self.prs.progress.get(&self.id);
        // Update
        self.is_learner = pr.is_some() && pr.as_ref().unwrap().is_learner;
        if (pr.is_none() || self.is_learner) && self.state == StateType::Leader {
            // This node is leader and was removed or demoted. We prevent demotions
            // at the time writing but hypothetically we handle them the same way as
            // removing the leader; stepping down into the next Term.
            //
            // TODO(tbg): step down (for sanity) and ask follower with largest Match
            // to TimeoutNow (to advoid interruption). This might still drop some
            // proposals but it's bette than nothing.
            //
            // TODO(tbg): test this branch. It is untested at the time of writing.
            return cs;
        }
        // The remaining steps only make sense if this node is the leader and there
        // are other nodes.
        if self.state != StateType::Leader || cs.get_voters().is_empty() {
            return cs;
        }
        if self.maybe_commit() {
            // If the configuration change means that more entries are committed now,
            // broadcast/append to everyone in the updated config.
            self.bcast_append();
        } else {
            // Otherwise, still probe the newly added replicas; there's no reason to
            // let them wait out a heartbeat interval (or the next incoming
            // proposal).
            // TODO:
            //
            self.prs.visit_nodes().iter_mut().for_each(|id| {
                self.maybe_send_append(*id, false);
            })
            //            self.prs.visit(|id, pr| {
            //                self.maybe_send_append(id, false);
            //            });
        }
        // If the leaderTransferee was removed or demoted, abort the leadership transfer.
        let t_ok = self.prs.config.voters.ids().contains(&self.lead_transferee);
        if !t_ok && self.lead_transferee != 0 {
            self.abort_leader_transferee();
        }
        cs
    }
pub ( crate ) fn switch_to_config ( & mut self , cfg : tracker :: Config , prs : ProgressMap ) -> ConfState { self . prs . config = cfg ; self . prs . progress = prs ; info ! ( " " self id self prs config ) ; let cs = self . prs . config_state ( ) ; let pr = self . prs . progress . get ( & self . id ) ; // Update self . is_learner = pr . is_some ( ) && pr . as_ref ( ) . unwrap ( ) . is_learner ; if ( pr . is_none ( ) || self . is_learner ) && self . state == StateType :: Leader { // This node is leader and was removed or demoted. We prevent demotions // at the time writing but hypothetically we handle them the same way as // removing the leader; stepping down into the next Term. // // TODO(tbg): step down (for sanity) and ask follower with largest Match // to TimeoutNow (to advoid interruption). This might still drop some // proposals but it's bette than nothing. // // TODO(tbg): test this branch. It is untested at the time of writing. return cs ; } // The remaining steps only make sense if this node is the leader and there // are other nodes. if self . state != StateType :: Leader || cs . get_voters ( ) . is_empty ( ) { return cs ; } if self . maybe_commit ( ) { // If the configuration change means that more entries are committed now, // broadcast/append to everyone in the updated config. self . bcast_append ( ) ; } else { // Otherwise, still probe the newly added replicas; there's no reason to // let them wait out a heartbeat interval (or the next incoming // proposal). // TODO: // self . prs . visit_nodes ( ) . iter_mut ( ) . for_each ( | id | { self . maybe_send_append ( * id , false ) ; } ) //            self.prs.visit(|id, pr| { //                self.maybe_send_append(id, false); //            }); } // If the leaderTransferee was removed or demoted, abort the leadership transfer. let t_ok = self . prs . config . voters . ids ( ) . contains ( & self . lead_transferee ) ; if ! t_ok && self . lead_transferee != 0 { self . abort_leader_transferee ( ) ; } cs }
switch_to_config reconfigures this node to use the provided configuration.
switch_to_config reconfigures this node to use the provided configuration .
&mut self
cfg
tracker::Config
prs
ProgressMap