@@ -21,7 +21,7 @@ pub struct DiscoveryMonitor {
2121 coordinator_wallet : Wallet ,
2222 compute_pool_id : u32 ,
2323 interval_s : u64 ,
24- discovery_url : String ,
24+ discovery_urls : Vec < String > ,
2525 store_context : Arc < StoreContext > ,
2626 heartbeats : Arc < LoopHeartbeats > ,
2727 http_client : reqwest:: Client ,
@@ -35,7 +35,7 @@ impl DiscoveryMonitor {
3535 coordinator_wallet : Wallet ,
3636 compute_pool_id : u32 ,
3737 interval_s : u64 ,
38- discovery_url : String ,
38+ discovery_urls : Vec < String > ,
3939 store_context : Arc < StoreContext > ,
4040 heartbeats : Arc < LoopHeartbeats > ,
4141 max_healthy_nodes_with_same_endpoint : u32 ,
@@ -45,7 +45,7 @@ impl DiscoveryMonitor {
4545 coordinator_wallet,
4646 compute_pool_id,
4747 interval_s,
48- discovery_url ,
48+ discovery_urls ,
4949 store_context,
5050 heartbeats,
5151 http_client : reqwest:: Client :: new ( ) ,
@@ -106,7 +106,10 @@ impl DiscoveryMonitor {
106106 self . heartbeats . update_monitor ( ) ;
107107 }
108108 }
109- pub async fn fetch_nodes_from_discovery ( & self ) -> Result < Vec < DiscoveryNode > , Error > {
109+ async fn fetch_nodes_from_single_discovery (
110+ & self ,
111+ discovery_url : & str ,
112+ ) -> Result < Vec < DiscoveryNode > , Error > {
110113 let discovery_route = format ! ( "/api/pool/{}" , self . compute_pool_id) ;
111114 let address = self . coordinator_wallet . address ( ) . to_string ( ) ;
112115
@@ -131,23 +134,29 @@ impl DiscoveryMonitor {
131134
132135 let response = match self
133136 . http_client
134- . get ( format ! ( "{}{}" , self . discovery_url, discovery_route) )
137+ . get ( format ! ( "{}{}" , discovery_url, discovery_route) )
135138 . query ( & [ ( "nonce" , signature. nonce ) ] )
136139 . headers ( headers)
137140 . send ( )
138141 . await
139142 {
140143 Ok ( resp) => resp,
141144 Err ( e) => {
142- error ! ( "Failed to fetch nodes from discovery service: {}" , e) ;
145+ error ! (
146+ "Failed to fetch nodes from discovery service {}: {}" ,
147+ discovery_url, e
148+ ) ;
143149 return Ok ( Vec :: new ( ) ) ;
144150 }
145151 } ;
146152
147153 let response_text = match response. text ( ) . await {
148154 Ok ( text) => text,
149155 Err ( e) => {
150- error ! ( "Failed to read discovery response: {}" , e) ;
156+ error ! (
157+ "Failed to read discovery response from {}: {}" ,
158+ discovery_url, e
159+ ) ;
151160 return Ok ( Vec :: new ( ) ) ;
152161 }
153162 } ;
@@ -156,7 +165,10 @@ impl DiscoveryMonitor {
156165 match serde_json:: from_str ( & response_text) {
157166 Ok ( resp) => resp,
158167 Err ( e) => {
159- error ! ( "Failed to parse discovery response: {}" , e) ;
168+ error ! (
169+ "Failed to parse discovery response from {}: {}" ,
170+ discovery_url, e
171+ ) ;
160172 return Ok ( Vec :: new ( ) ) ;
161173 }
162174 } ;
@@ -170,6 +182,48 @@ impl DiscoveryMonitor {
170182 Ok ( nodes)
171183 }
172184
185+ pub async fn fetch_nodes_from_discovery ( & self ) -> Result < Vec < DiscoveryNode > , Error > {
186+ let mut all_nodes = Vec :: new ( ) ;
187+ let mut any_success = false ;
188+
189+ for discovery_url in & self . discovery_urls {
190+ match self . fetch_nodes_from_single_discovery ( discovery_url) . await {
191+ Ok ( nodes) => {
192+ info ! (
193+ "Successfully fetched {} nodes from {}" ,
194+ nodes. len( ) ,
195+ discovery_url
196+ ) ;
197+ all_nodes. extend ( nodes) ;
198+ any_success = true ;
199+ }
200+ Err ( e) => {
201+ error ! ( "Failed to fetch nodes from {}: {}" , discovery_url, e) ;
202+ }
203+ }
204+ }
205+
206+ if !any_success {
207+ error ! ( "Failed to fetch nodes from all discovery services" ) ;
208+ return Ok ( Vec :: new ( ) ) ;
209+ }
210+
211+ // Remove duplicates based on node ID
212+ let mut unique_nodes = Vec :: new ( ) ;
213+ let mut seen_ids = std:: collections:: HashSet :: new ( ) ;
214+ for node in all_nodes {
215+ if seen_ids. insert ( node. node . id . clone ( ) ) {
216+ unique_nodes. push ( node) ;
217+ }
218+ }
219+
220+ info ! (
221+ "Total unique nodes after deduplication: {}" ,
222+ unique_nodes. len( )
223+ ) ;
224+ Ok ( unique_nodes)
225+ }
226+
173227 async fn count_healthy_nodes_with_same_endpoint (
174228 & self ,
175229 node_address : Address ,
@@ -422,7 +476,7 @@ mod tests {
422476 fake_wallet,
423477 1 ,
424478 10 ,
425- "http://localhost:8080" . to_string ( ) ,
479+ vec ! [ "http://localhost:8080" . to_string( ) ] ,
426480 discovery_store_context,
427481 Arc :: new ( LoopHeartbeats :: new ( & mode) ) ,
428482 1 ,
@@ -503,7 +557,7 @@ mod tests {
503557 fake_wallet,
504558 1 ,
505559 10 ,
506- "http://localhost:8080" . to_string ( ) ,
560+ vec ! [ "http://localhost:8080" . to_string( ) ] ,
507561 store_context. clone ( ) ,
508562 Arc :: new ( LoopHeartbeats :: new ( & mode) ) ,
509563 1 ,
@@ -652,7 +706,7 @@ mod tests {
652706 fake_wallet,
653707 1 ,
654708 10 ,
655- "http://localhost:8080" . to_string ( ) ,
709+ vec ! [ "http://localhost:8080" . to_string( ) ] ,
656710 store_context. clone ( ) ,
657711 Arc :: new ( LoopHeartbeats :: new ( & mode) ) ,
658712 1 ,
0 commit comments