locator::topology: allow being_replaced and replacing nodes to have the same IP

When we're replacing a node with the same IP address, we want
the following behavior:
  * host_id -> IP mapping should work and return the same IP address for two
  different host_ids - old and new.
  * the IP -> host_id mapping should return the host_id of the old (replaced)
  host.
This variant is most convenient for preserving the current behavior
of the code, especially the functions maybe_remove_node_being_replaced,
erm::get_natural_endpoints_without_node_being_replaced,
erm::get_pending_endpoints. The 'being_replaced' node will be properly removed in
maybe_remove_node_being_replaced and 'replacing' node will be added to
the pending_endpoints.
This commit is contained in:
Petr Gusev
2023-12-04 13:11:50 +04:00
parent 5a1418fdba
commit e4253776a1

View File

@@ -318,7 +318,12 @@ void topology::index_node(const node* node) {
if (node->endpoint() != inet_address{}) {
auto eit = _nodes_by_endpoint.find(node->endpoint());
if (eit != _nodes_by_endpoint.end()) {
if (eit->second->is_leaving() || eit->second->left()) {
if (eit->second->get_state() == node::state::replacing && node->get_state() == node::state::being_replaced) {
// replace-with-same-ip, map ip to the old node
_nodes_by_endpoint.erase(node->endpoint());
} else if (eit->second->get_state() == node::state::being_replaced && node->get_state() == node::state::replacing) {
// replace-with-same-ip, map ip to the old node, do nothing if it's already the case
} else if (eit->second->is_leaving() || eit->second->left()) {
_nodes_by_endpoint.erase(node->endpoint());
} else if (!node->is_leaving() && !node->left()) {
if (node->host_id()) {