@@ -846,38 +846,36 @@ namespace aft
846846 node.second .last_ack_timeout += elapsed;
847847 }
848848
849- bool has_quorum_of_backups = false ;
850- for (auto const & conf : configurations)
851- {
852- size_t backup_ack_timeout_count = 0 ;
853- for (auto const & node : conf.nodes )
854- {
855- auto search = all_other_nodes.find (node.first );
856- if (search == all_other_nodes.end ())
857- {
858- // Ignore ourselves as primary
859- continue ;
860- }
861- if (search->second .last_ack_timeout >= election_timeout)
849+ bool every_active_config_has_a_quorum = std::all_of (
850+ configurations.begin (),
851+ configurations.end (),
852+ [this ](const Configuration& conf) {
853+ size_t live_nodes_in_config = 0 ;
854+ for (auto const & node : conf.nodes )
862855 {
863- RAFT_DEBUG_FMT (
864- " No ack received from {} in last {}" ,
865- node.first ,
866- election_timeout);
867- backup_ack_timeout_count++;
856+ auto search = all_other_nodes.find (node.first );
857+ if (
858+ // if a (non-self) node is in a configuration, then it is in
859+ // all_other_nodes. So if a node in a configuration is not found
860+ // in all_other_nodes, it must be self, and hence is live
861+ search == all_other_nodes.end () ||
862+ // Otherwise we use the most recent ack as a failure probe
863+ search->second .last_ack_timeout < election_timeout)
864+ {
865+ ++live_nodes_in_config;
866+ }
867+ else
868+ {
869+ RAFT_DEBUG_FMT (
870+ " No ack received from {} in last {}" ,
871+ node.first ,
872+ election_timeout);
873+ }
868874 }
869- }
870-
871- if (backup_ack_timeout_count < get_quorum (conf.nodes .size () - 1 ))
872- {
873- // If primary has quorum of active backups in _any_ configuration,
874- // it should remain primary
875- has_quorum_of_backups = true ;
876- break ;
877- }
878- }
875+ return live_nodes_in_config >= get_quorum (conf.nodes .size ());
876+ });
879877
880- if (!has_quorum_of_backups )
878+ if (!every_active_config_has_a_quorum )
881879 {
882880 // CheckQuorum: The primary automatically steps down if there are no
883881 // active configuration in which it has heard back from a majority of
0 commit comments