@@ -3,6 +3,7 @@ use std::{
3
3
atomic:: { AtomicBool , AtomicUsize , Ordering } ,
4
4
Arc ,
5
5
} ,
6
+ time:: Duration ,
6
7
vec,
7
8
} ;
8
9
@@ -144,7 +145,6 @@ pub async fn send_batched_transactions<T: TransactionBuilder, R: RpcConnection>(
144
145
return Ok ( 0 ) ;
145
146
}
146
147
147
- // Get priority fee and blockhash
148
148
let ( recent_blockhash, current_block_height) = {
149
149
let mut rpc = pool. get_connection ( ) . await ?;
150
150
(
@@ -202,7 +202,6 @@ pub async fn send_batched_transactions<T: TransactionBuilder, R: RpcConnection>(
202
202
}
203
203
} ) ;
204
204
205
- // Process work items in chunks of `config.build_transaction_batch_config.batch_size`
206
205
let work_items: Vec < WorkItem > = queue_item_data
207
206
. into_iter ( )
208
207
. map ( |data| WorkItem {
@@ -211,10 +210,16 @@ pub async fn send_batched_transactions<T: TransactionBuilder, R: RpcConnection>(
211
210
} )
212
211
. collect ( ) ;
213
212
213
+ let buffer_duration = Duration :: from_secs ( 2 ) ;
214
+ let adjusted_timeout = if config. retry_config . timeout > buffer_duration {
215
+ config. retry_config . timeout - buffer_duration
216
+ } else {
217
+ return Ok ( 0 ) ;
218
+ } ;
219
+ let timeout_deadline = start_time + adjusted_timeout;
220
+
214
221
for work_chunk in work_items. chunks ( config. build_transaction_batch_config . batch_size as usize ) {
215
- if cancel_signal. load ( Ordering :: SeqCst )
216
- || start_time. elapsed ( ) >= config. retry_config . timeout
217
- {
222
+ if cancel_signal. load ( Ordering :: SeqCst ) || Instant :: now ( ) >= timeout_deadline {
218
223
break ;
219
224
}
220
225
@@ -230,12 +235,22 @@ pub async fn send_batched_transactions<T: TransactionBuilder, R: RpcConnection>(
230
235
)
231
236
. await ?;
232
237
233
- // Spawn transaction senders
238
+ let now = Instant :: now ( ) ;
239
+ if now >= timeout_deadline {
240
+ break ;
241
+ }
242
+
234
243
for tx in transactions {
235
244
if cancel_signal. load ( Ordering :: SeqCst ) {
236
245
break ;
237
246
}
238
247
248
+ let now = Instant :: now ( ) ;
249
+ if now >= timeout_deadline {
250
+ warn ! ( "Reached timeout deadline, stopping batch processing" ) ;
251
+ break ;
252
+ }
253
+
239
254
let tx_sender = tx_sender. clone ( ) ;
240
255
let pool_clone = pool. clone ( ) ;
241
256
let config = RpcSendTransactionConfig {
@@ -245,21 +260,25 @@ pub async fn send_batched_transactions<T: TransactionBuilder, R: RpcConnection>(
245
260
..Default :: default ( )
246
261
} ;
247
262
263
+ let cancel_signal_clone = cancel_signal. clone ( ) ;
264
+ let deadline = timeout_deadline;
265
+
248
266
tokio:: spawn ( async move {
267
+ if cancel_signal_clone. load ( Ordering :: SeqCst ) || Instant :: now ( ) >= deadline {
268
+ return ;
269
+ }
270
+
249
271
if let Ok ( mut rpc) = pool_clone. get_connection ( ) . await {
250
272
let result = rpc. process_transaction_with_config ( tx, config) . await ;
251
- let _ = tx_sender. send ( result) . await ;
273
+ if !cancel_signal_clone. load ( Ordering :: SeqCst ) {
274
+ let _ = tx_sender. send ( result) . await ;
275
+ }
252
276
}
253
277
} ) ;
254
278
}
255
279
}
256
-
257
- // Drop sender to allow processor to complete
258
280
drop ( tx_sender) ;
259
-
260
- // Wait for processor to complete
261
281
processor_handle. await ?;
262
-
263
282
Ok ( num_sent_transactions. load ( Ordering :: SeqCst ) )
264
283
}
265
284
0 commit comments