Skip to content

Commit

Permalink
Add retry to fetcher (ordinals#2297)
Browse files Browse the repository at this point in the history
  • Loading branch information
victorkirov authored Jul 23, 2023
1 parent abcc927 commit 1efb044
Showing 1 changed file with 53 additions and 12 deletions.
65 changes: 53 additions & 12 deletions src/index/fetcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,23 +65,38 @@ impl Fetcher {
}

let body = Value::Array(reqs).to_string();
let req = Request::builder()
.method(Method::POST)
.uri(&self.url)
.header(hyper::header::AUTHORIZATION, &self.auth)
.header(hyper::header::CONTENT_TYPE, "application/json")
.body(Body::from(body))?;

let response = self.client.request(req).await?;

let buf = hyper::body::to_bytes(response).await?;

let mut results: Vec<JsonResponse<String>> = serde_json::from_slice(&buf)?;
let mut results: Vec<JsonResponse<String>>;
let mut retries = 0;

loop {
results = match self.try_get_transactions(body.clone()).await {
Ok(results) => results,
Err(error) => {
if retries >= 5 {
return Err(anyhow!(
"failed to fetch raw transactions after 5 retries: {}",
error
));
}

log::info!("failed to fetch raw transactions, retrying: {}", error);

tokio::time::sleep(tokio::time::Duration::from_millis(
100 * u64::pow(2, retries),
))
.await;
retries += 1;
continue;
}
};
break;
}

// Return early on any error, because we need all results to proceed
if let Some(err) = results.iter().find_map(|res| res.error.as_ref()) {
return Err(anyhow!(
"Failed to fetch raw transaction: code {} message {}",
"failed to fetch raw transaction: code {} message {}",
err.code,
err.message
));
Expand Down Expand Up @@ -109,4 +124,30 @@ impl Fetcher {
.collect::<Result<Vec<Transaction>>>()?;
Ok(txs)
}

async fn try_get_transactions(&self, body: String) -> Result<Vec<JsonResponse<String>>> {
let req = Request::builder()
.method(Method::POST)
.uri(&self.url)
.header(hyper::header::AUTHORIZATION, &self.auth)
.header(hyper::header::CONTENT_TYPE, "application/json")
.body(Body::from(body))?;

let response = self.client.request(req).await?;

let buf = hyper::body::to_bytes(response).await?;

let results: Vec<JsonResponse<String>> = match serde_json::from_slice(&buf) {
Ok(results) => results,
Err(e) => {
return Err(anyhow!(
"failed to parse JSON-RPC response: {e}. response: {response}",
e = e,
response = String::from_utf8_lossy(&buf)
))
}
};

Ok(results)
}
}

0 comments on commit 1efb044

Please sign in to comment.