@@ -26,6 +26,7 @@ use clarity::vm::analysis::contract_interface_builder::build_contract_interface;
26
26
use clarity:: vm:: costs:: ExecutionCost ;
27
27
use clarity:: vm:: events:: { FTEventType , NFTEventType , STXEventType } ;
28
28
use clarity:: vm:: types:: { AssetIdentifier , QualifiedContractIdentifier , Value } ;
29
+ use rand:: Rng ;
29
30
use rusqlite:: { params, Connection } ;
30
31
use serde_json:: json;
31
32
use stacks:: burnchains:: { PoxConstants , Txid } ;
@@ -429,6 +430,10 @@ impl EventObserver {
429
430
. unwrap_or ( PeerHost :: DNS ( host. to_string ( ) , port) ) ;
430
431
431
432
let mut backoff = Duration :: from_millis ( 100 ) ;
433
+ let mut attempts: i32 = 0 ;
434
+ // Cap the backoff at 3x the timeout
435
+ let max_backoff = timeout. saturating_mul ( 3 ) ;
436
+
432
437
loop {
433
438
let mut request = StacksHttpRequest :: new_for_peer (
434
439
peerhost. clone ( ) ,
@@ -438,7 +443,6 @@ impl EventObserver {
438
443
)
439
444
. unwrap_or_else ( |_| panic ! ( "FATAL: failed to encode infallible data as HTTP request" ) ) ;
440
445
request. add_header ( "Connection" . into ( ) , "close" . into ( ) ) ;
441
-
442
446
match send_http_request ( host, port, request, timeout) {
443
447
Ok ( response) => {
444
448
if response. preamble ( ) . status_code == 200 {
@@ -455,7 +459,9 @@ impl EventObserver {
455
459
Err ( err) => {
456
460
warn ! (
457
461
"Event dispatcher: connection or request failed to {}:{} - {:?}" ,
458
- & host, & port, err
462
+ & host, & port, err;
463
+ "backoff" => ?backoff,
464
+ "attempts" => attempts
459
465
) ;
460
466
}
461
467
}
@@ -471,7 +477,12 @@ impl EventObserver {
471
477
}
472
478
473
479
sleep ( backoff) ;
474
- backoff *= 2 ;
480
+ let jitter: u64 = rand:: thread_rng ( ) . gen_range ( 0 ..100 ) ;
481
+ backoff = std:: cmp:: min (
482
+ backoff. saturating_mul ( 2 ) + Duration :: from_millis ( jitter) ,
483
+ max_backoff,
484
+ ) ;
485
+ attempts = attempts. saturating_add ( 1 ) ;
475
486
}
476
487
}
477
488
0 commit comments