@@ -217,29 +217,28 @@ impl ConnectionWorkersScheduler {
217
217
}
218
218
} ;
219
219
220
- let updated_leaders = leader_updater. next_leaders ( leaders_fanout. connect ) ;
220
+ let connect_leaders = leader_updater. next_leaders ( leaders_fanout. connect ) ;
221
+ let send_leaders = extract_send_leaders ( & connect_leaders, leaders_fanout. send ) ;
221
222
222
- let ( fanout_leaders, connect_leaders) =
223
- split_leaders ( & updated_leaders, & leaders_fanout) ;
224
223
// add future leaders to the cache to hide the latency of opening
225
224
// the connection.
226
225
for peer in connect_leaders {
227
- if !workers. contains ( peer) {
226
+ if !workers. contains ( & peer) {
228
227
let stats = send_stats_per_addr. entry ( peer. ip ( ) ) . or_default ( ) ;
229
228
let worker = Self :: spawn_worker (
230
229
& endpoint,
231
- peer,
230
+ & peer,
232
231
worker_channel_size,
233
232
skip_check_transaction_age,
234
233
max_reconnect_attempts,
235
234
stats. clone ( ) ,
236
235
) ;
237
- maybe_shutdown_worker ( workers. push ( * peer, worker) ) ;
236
+ maybe_shutdown_worker ( workers. push ( peer, worker) ) ;
238
237
}
239
238
}
240
239
241
240
if let Err ( error) =
242
- Broadcaster :: send_to_workers ( & mut workers, fanout_leaders , transaction_batch) . await
241
+ Broadcaster :: send_to_workers ( & mut workers, & send_leaders , transaction_batch) . await
243
242
{
244
243
last_error = Some ( error) ;
245
244
break ;
@@ -338,21 +337,23 @@ impl WorkersBroadcaster for NonblockingBroadcaster {
338
337
}
339
338
}
340
339
341
- /// Splits `leaders` into two slices based on the `fanout` configuration:
342
- /// * the first slice contains the leaders to which transactions will be sent,
343
- /// * the second vector contains the leaders, used to warm up connections. This
344
- /// slice includes the first set.
345
- fn split_leaders < ' leaders > (
346
- leaders : & ' leaders [ SocketAddr ] ,
347
- fanout : & Fanout ,
348
- ) -> ( & ' leaders [ SocketAddr ] , & ' leaders [ SocketAddr ] ) {
349
- let Fanout { send, connect } = fanout;
350
- assert ! ( send <= connect) ;
351
- let send_count = ( * send) . min ( leaders. len ( ) ) ;
352
- let connect_count = ( * connect) . min ( leaders. len ( ) ) ;
353
-
354
- let send_slice = & leaders[ ..send_count] ;
355
- let connect_slice = & leaders[ ..connect_count] ;
356
-
357
- ( send_slice, connect_slice)
340
+ /// Extracts a list of unique leader addresses to which transactions will be sent.
341
+ ///
342
+ /// This function selects up to `send_fanout` addresses from the `leaders` list, ensuring that
343
+ /// only unique addresses are included while maintaining their original order.
344
+ fn extract_send_leaders ( leaders : & [ SocketAddr ] , send_fanout : usize ) -> Vec < SocketAddr > {
345
+ let send_count = send_fanout. min ( leaders. len ( ) ) ;
346
+ remove_duplicates ( & leaders[ ..send_count] )
347
+ }
348
+
349
+ /// Removes duplicate `SocketAddr` elements from the given slice while
350
+ /// preserving their original order.
351
+ fn remove_duplicates ( input : & [ SocketAddr ] ) -> Vec < SocketAddr > {
352
+ let mut res = Vec :: with_capacity ( input. len ( ) ) ;
353
+ for address in input {
354
+ if !res. contains ( address) {
355
+ res. push ( * address) ;
356
+ }
357
+ }
358
+ res
358
359
}
0 commit comments