add a spot for retries
This commit is contained in:
parent
0769e26afb
commit
aa3b40e03f
|
@ -47,7 +47,7 @@ use std::time::Duration;
|
||||||
use tokio::select;
|
use tokio::select;
|
||||||
use tokio::sync::{broadcast, mpsc, oneshot, watch, Semaphore};
|
use tokio::sync::{broadcast, mpsc, oneshot, watch, Semaphore};
|
||||||
use tokio::task::{yield_now, JoinHandle};
|
use tokio::task::{yield_now, JoinHandle};
|
||||||
use tokio::time::{sleep, timeout, timeout_at, Instant};
|
use tokio::time::{sleep, sleep_until, timeout, timeout_at, Instant};
|
||||||
use tracing::{error, info, trace, warn};
|
use tracing::{error, info, trace, warn};
|
||||||
|
|
||||||
// TODO: make this customizable?
|
// TODO: make this customizable?
|
||||||
|
@ -1095,13 +1095,25 @@ impl App {
|
||||||
// TODO: this clone is only for an error response. refactor to not need it
|
// TODO: this clone is only for an error response. refactor to not need it
|
||||||
let error_id = request.id.clone();
|
let error_id = request.id.clone();
|
||||||
|
|
||||||
let web3_request = match ValidatedRequest::new_with_app(
|
let mut last_success = None;
|
||||||
|
let mut last_error = None;
|
||||||
|
let mut web3_request;
|
||||||
|
|
||||||
|
// TODO: think more about how to handle retries without hammering our servers with errors
|
||||||
|
let mut ranked_rpcs = self.balanced_rpcs.watch_ranked_rpcs.subscribe();
|
||||||
|
|
||||||
|
let latest_start = Instant::now() + Duration::from_secs(3);
|
||||||
|
|
||||||
|
// TODO: how many retries?
|
||||||
|
loop {
|
||||||
|
// TODO: refresh the request instead of making new each time. then we need less clones
|
||||||
|
web3_request = match ValidatedRequest::new_with_app(
|
||||||
self,
|
self,
|
||||||
authorization,
|
authorization.clone(),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
request.into(),
|
request.clone().into(),
|
||||||
head_block,
|
head_block.clone(),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
|
@ -1109,14 +1121,42 @@ impl App {
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let (a, b) = err.as_json_response_parts(error_id);
|
let (a, b) = err.as_json_response_parts(error_id);
|
||||||
|
|
||||||
return (a, b, vec![]);
|
let rpcs = vec![];
|
||||||
|
|
||||||
|
return (a, b, rpcs);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: trace/kafka log request.params before we send them to _proxy_request_with_caching which might modify them
|
|
||||||
|
|
||||||
// turn some of the Web3ProxyErrors into Ok results
|
// turn some of the Web3ProxyErrors into Ok results
|
||||||
let (code, response) = match self._proxy_request_with_caching(&web3_request).await {
|
match self._proxy_request_with_caching(&web3_request).await {
|
||||||
|
Ok(response_data) => {
|
||||||
|
last_success = Some(response_data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
last_error = Some(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
select! {
|
||||||
|
_ = ranked_rpcs.changed() => {
|
||||||
|
// TODO: pass these RankedRpcs to ValidatedRequest::new_with_app
|
||||||
|
ranked_rpcs.borrow_and_update();
|
||||||
|
}
|
||||||
|
_ = sleep_until(latest_start) => {
|
||||||
|
// do not retry if we've already been trying for 3 seconds
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let last_response = if let Some(last_success) = last_success {
|
||||||
|
Ok(last_success)
|
||||||
|
} else {
|
||||||
|
Err(last_error.unwrap_or(anyhow::anyhow!("no success or error").into()))
|
||||||
|
};
|
||||||
|
|
||||||
|
let (code, response) = match last_response {
|
||||||
Ok(response_data) => {
|
Ok(response_data) => {
|
||||||
web3_request.error_response.store(false, Ordering::Relaxed);
|
web3_request.error_response.store(false, Ordering::Relaxed);
|
||||||
web3_request
|
web3_request
|
||||||
|
|
Loading…
Reference in New Issue