Skip to content

Commit 1c595ad

Browse files
committed
feat: various improvements to retry logic in event dispatcher
- Create the request outside the loop - Cap the backoff timeout at 3x timeout - Print the retry attempt and backoff time in the log - Add a jitter to the backoff time
1 parent 2207ac4 commit 1c595ad

File tree

1 file changed

+20
-11
lines changed

1 file changed

+20
-11
lines changed

testnet/stacks-node/src/event_dispatcher.rs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use clarity::vm::analysis::contract_interface_builder::build_contract_interface;
2626
use clarity::vm::costs::ExecutionCost;
2727
use clarity::vm::events::{FTEventType, NFTEventType, STXEventType};
2828
use clarity::vm::types::{AssetIdentifier, QualifiedContractIdentifier, Value};
29+
use rand::Rng;
2930
use rusqlite::{params, Connection};
3031
use serde_json::json;
3132
use stacks::burnchains::{PoxConstants, Txid};
@@ -429,17 +430,19 @@ impl EventObserver {
429430
.unwrap_or(PeerHost::DNS(host.to_string(), port));
430431

431432
let mut backoff = Duration::from_millis(100);
433+
let mut attempts: i32 = 0;
434+
// Cap the backoff at 3x the timeout
432435
let max_backoff = timeout.saturating_mul(3);
433-
loop {
434-
let mut request = StacksHttpRequest::new_for_peer(
435-
peerhost.clone(),
436-
"POST".into(),
437-
url.path().into(),
438-
HttpRequestContents::new().payload_json(payload.clone()),
439-
)
440-
.unwrap_or_else(|_| panic!("FATAL: failed to encode infallible data as HTTP request"));
441-
request.add_header("Connection".into(), "close".into());
442436

437+
let mut request = StacksHttpRequest::new_for_peer(
438+
peerhost.clone(),
439+
"POST".into(),
440+
url.path().into(),
441+
HttpRequestContents::new().payload_json(payload.clone()),
442+
)
443+
.unwrap_or_else(|_| panic!("FATAL: failed to encode infallible data as HTTP request"));
444+
request.add_header("Connection".into(), "close".into());
445+
loop {
443446
match send_http_request(host, port, request, timeout) {
444447
Ok(response) => {
445448
if response.preamble().status_code == 200 {
@@ -457,7 +460,8 @@ impl EventObserver {
457460
warn!(
458461
"Event dispatcher: connection or request failed to {}:{} - {:?}",
459462
&host, &port, err;
460-
"backoff" => backoff
463+
"backoff" => backoff,
464+
"attempts" => attempts
461465
);
462466
}
463467
}
@@ -473,7 +477,12 @@ impl EventObserver {
473477
}
474478

475479
sleep(backoff);
476-
backoff = std::cmp::min(backoff.saturating_mul(2), max_backoff);
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);
477486
}
478487
}
479488

0 commit comments

Comments
 (0)