@@ -2130,15 +2130,15 @@ def signal_connection_failure(self, host, connection_exc, is_host_addition, expe
2130
2130
self .on_down (host , is_host_addition , expect_host_to_be_down )
2131
2131
return is_down
2132
2132
2133
- def add_host (self , endpoint , datacenter = None , rack = None , signal = True , refresh_nodes = True ):
2133
+ def add_host (self , endpoint , datacenter = None , rack = None , signal = True , refresh_nodes = True , host_id = None ):
2134
2134
"""
2135
2135
Called when adding initial contact points and when the control
2136
2136
connection subsequently discovers a new node.
2137
2137
Returns a Host instance, and a flag indicating whether it was new in
2138
2138
the metadata.
2139
2139
Intended for internal use only.
2140
2140
"""
2141
- host , new = self .metadata .add_or_return_host (Host (endpoint , self .conviction_policy_factory , datacenter , rack ))
2141
+ host , new = self .metadata .add_or_return_host (Host (endpoint , self .conviction_policy_factory , datacenter , rack , host_id = host_id ))
2142
2142
if new and signal :
2143
2143
log .info ("New Cassandra host %r discovered" , host )
2144
2144
self .on_add (host , refresh_nodes )
@@ -3817,9 +3817,8 @@ def _refresh_node_list_and_token_map(self, connection, preloaded_results=None,
3817
3817
partitioner = None
3818
3818
token_map = {}
3819
3819
3820
- found_hosts = set ()
3820
+ found_host_ids = set ()
3821
3821
if local_result .parsed_rows :
3822
- found_hosts .add (connection .endpoint )
3823
3822
local_rows = dict_factory (local_result .column_names , local_result .parsed_rows )
3824
3823
local_row = local_rows [0 ]
3825
3824
cluster_name = local_row ["cluster_name" ]
@@ -3833,7 +3832,9 @@ def _refresh_node_list_and_token_map(self, connection, preloaded_results=None,
3833
3832
datacenter = local_row .get ("data_center" )
3834
3833
rack = local_row .get ("rack" )
3835
3834
self ._update_location_info (host , datacenter , rack )
3835
+ host .endpoint = self ._cluster .endpoint_factory .create (local_row )
3836
3836
host .host_id = local_row .get ("host_id" )
3837
+ found_host_ids .add (host .host_id )
3837
3838
host .listen_address = local_row .get ("listen_address" )
3838
3839
host .listen_port = local_row .get ("listen_port" )
3839
3840
host .broadcast_address = _NodeInfo .get_broadcast_address (local_row )
@@ -3872,6 +3873,8 @@ def _refresh_node_list_and_token_map(self, connection, preloaded_results=None,
3872
3873
if partitioner and tokens :
3873
3874
token_map [host ] = tokens
3874
3875
3876
+ self ._cluster .metadata .update_host (host , old_endpoint = connection .endpoint )
3877
+ connection .original_endpoint = connection .endpoint = host .endpoint
3875
3878
# Check metadata.partitioner to see if we haven't built anything yet. If
3876
3879
# every node in the cluster was in the contact points, we won't discover
3877
3880
# any new nodes, so we need this additional check. (See PYTHON-90)
@@ -3884,24 +3887,26 @@ def _refresh_node_list_and_token_map(self, connection, preloaded_results=None,
3884
3887
continue
3885
3888
3886
3889
endpoint = self ._cluster .endpoint_factory .create (row )
3890
+ host_id = row .get ("host_id" )
3887
3891
3888
- if endpoint in found_hosts :
3889
- log .warning ("Found multiple hosts with the same endpoint (%s). Excluding peer %s" , endpoint , row .get ("peer" ))
3892
+ if host_id in found_host_ids :
3893
+ log .warning ("Found multiple hosts with the same host_id (%s). Excluding peer %s" , host_id , row .get ("peer" ))
3890
3894
continue
3891
3895
3892
- found_hosts .add (endpoint )
3896
+ found_host_ids .add (host_id )
3893
3897
3894
3898
host = self ._cluster .metadata .get_host (endpoint )
3895
3899
datacenter = row .get ("data_center" )
3896
3900
rack = row .get ("rack" )
3901
+
3897
3902
if host is None :
3898
3903
log .debug ("[control connection] Found new host to connect to: %s" , endpoint )
3899
- host , _ = self ._cluster .add_host (endpoint , datacenter , rack , signal = True , refresh_nodes = False )
3904
+ host , _ = self ._cluster .add_host (endpoint , datacenter = datacenter , rack = rack , signal = True , refresh_nodes = False , host_id = host_id )
3900
3905
should_rebuild_token_map = True
3901
3906
else :
3902
3907
should_rebuild_token_map |= self ._update_location_info (host , datacenter , rack )
3903
3908
3904
- host .host_id = row . get ( " host_id" )
3909
+ host .host_id = host_id
3905
3910
host .broadcast_address = _NodeInfo .get_broadcast_address (row )
3906
3911
host .broadcast_port = _NodeInfo .get_broadcast_port (row )
3907
3912
host .broadcast_rpc_address = _NodeInfo .get_broadcast_rpc_address (row )
@@ -3915,11 +3920,11 @@ def _refresh_node_list_and_token_map(self, connection, preloaded_results=None,
3915
3920
if partitioner and tokens and self ._token_meta_enabled :
3916
3921
token_map [host ] = tokens
3917
3922
3918
- for old_host in self ._cluster .metadata .all_hosts ():
3919
- if old_host . endpoint . address != connection . endpoint and old_host . endpoint not in found_hosts :
3923
+ for old_host_id , old_host in self ._cluster .metadata .all_hosts_items ():
3924
+ if old_host_id not in found_host_ids :
3920
3925
should_rebuild_token_map = True
3921
3926
log .debug ("[control connection] Removing host not found in peers metadata: %r" , old_host )
3922
- self ._cluster .remove_host ( old_host )
3927
+ self ._cluster .metadata . remove_host_by_host_id ( old_host_id )
3923
3928
3924
3929
log .debug ("[control connection] Finished fetching ring info" )
3925
3930
if partitioner and should_rebuild_token_map :
0 commit comments