@@ -24,6 +24,7 @@ pub struct DiscoveryMonitor {
2424 store_context : Arc < StoreContext > ,
2525 heartbeats : Arc < LoopHeartbeats > ,
2626 http_client : reqwest:: Client ,
27+ max_healthy_nodes_with_same_endpoint : u32 ,
2728}
2829
2930impl DiscoveryMonitor {
@@ -34,6 +35,7 @@ impl DiscoveryMonitor {
3435 discovery_url : String ,
3536 store_context : Arc < StoreContext > ,
3637 heartbeats : Arc < LoopHeartbeats > ,
38+ max_healthy_nodes_with_same_endpoint : u32 ,
3739 ) -> Self {
3840 Self {
3941 coordinator_wallet,
@@ -43,6 +45,7 @@ impl DiscoveryMonitor {
4345 store_context,
4446 heartbeats,
4547 http_client : reqwest:: Client :: new ( ) ,
48+ max_healthy_nodes_with_same_endpoint,
4649 }
4750 }
4851
@@ -127,19 +130,22 @@ impl DiscoveryMonitor {
127130 Ok ( nodes)
128131 }
129132
130- async fn has_healthy_node_with_same_endpoint (
133+ async fn count_healthy_nodes_with_same_endpoint (
131134 & self ,
132135 node_address : Address ,
133136 ip_address : & str ,
134137 port : u16 ,
135- ) -> Result < bool , Error > {
138+ ) -> Result < u32 , Error > {
136139 let nodes = self . store_context . node_store . get_nodes ( ) . await ?;
137- Ok ( nodes. iter ( ) . any ( |other_node| {
138- other_node. address != node_address
139- && other_node. ip_address == ip_address
140- && other_node. port == port
141- && other_node. status == NodeStatus :: Healthy
142- } ) )
140+ Ok ( nodes
141+ . iter ( )
142+ . filter ( |other_node| {
143+ other_node. address != node_address
144+ && other_node. ip_address == ip_address
145+ && other_node. port == port
146+ && other_node. status == NodeStatus :: Healthy
147+ } )
148+ . count ( ) as u32 )
143149 }
144150
145151 async fn sync_single_node_with_discovery (
@@ -149,8 +155,8 @@ impl DiscoveryMonitor {
149155 let node_address = discovery_node. node . id . parse :: < Address > ( ) ?;
150156
151157 // Check if there's any healthy node with the same IP and port
152- let has_healthy_node_same_endpoint = self
153- . has_healthy_node_with_same_endpoint (
158+ let count_healthy_nodes_with_same_endpoint = self
159+ . count_healthy_nodes_with_same_endpoint (
154160 node_address,
155161 & discovery_node. node . ip_address ,
156162 discovery_node. node . port ,
@@ -160,7 +166,9 @@ impl DiscoveryMonitor {
160166 match self . store_context . node_store . get_node ( & node_address) . await {
161167 Ok ( Some ( existing_node) ) => {
162168 // If there's a healthy node with same IP and port, and this node isn't healthy, mark it dead
163- if has_healthy_node_same_endpoint && existing_node. status != NodeStatus :: Healthy {
169+ if count_healthy_nodes_with_same_endpoint > 0
170+ && existing_node. status != NodeStatus :: Healthy
171+ {
164172 info ! (
165173 "Node {} shares endpoint {}:{} with a healthy node, marking as dead" ,
166174 node_address, discovery_node. node. ip_address, discovery_node. node. port
@@ -268,7 +276,9 @@ impl DiscoveryMonitor {
268276 }
269277 Ok ( None ) => {
270278 // Don't add new node if there's already a healthy node with same IP and port
271- if has_healthy_node_same_endpoint {
279+ if count_healthy_nodes_with_same_endpoint
280+ >= self . max_healthy_nodes_with_same_endpoint
281+ {
272282 info ! (
273283 "Skipping new node {} as endpoint {}:{} is already used by a healthy node" ,
274284 node_address, discovery_node. node. ip_address, discovery_node. node. port
@@ -387,6 +397,7 @@ mod tests {
387397 "http://localhost:8080" . to_string ( ) ,
388398 discovery_store_context,
389399 Arc :: new ( LoopHeartbeats :: new ( & mode) ) ,
400+ 1 ,
390401 ) ;
391402
392403 let store_context_clone = store_context. clone ( ) ;
@@ -466,6 +477,7 @@ mod tests {
466477 "http://localhost:8080" . to_string ( ) ,
467478 store_context. clone ( ) ,
468479 Arc :: new ( LoopHeartbeats :: new ( & mode) ) ,
480+ 1 ,
469481 ) ;
470482
471483 let time_before = Utc :: now ( ) ;
@@ -613,6 +625,7 @@ mod tests {
613625 "http://localhost:8080" . to_string ( ) ,
614626 store_context. clone ( ) ,
615627 Arc :: new ( LoopHeartbeats :: new ( & mode) ) ,
628+ 1 ,
616629 ) ;
617630
618631 // Try to sync the second node
0 commit comments