better handling when method not available
This commit is contained in:
parent
447cf90eed
commit
106dec294f
@ -749,6 +749,7 @@ impl Web3Connections {
|
|||||||
wait_for_sync: bool,
|
wait_for_sync: bool,
|
||||||
) -> anyhow::Result<JsonRpcForwardedResponse> {
|
) -> anyhow::Result<JsonRpcForwardedResponse> {
|
||||||
let mut skip_rpcs = vec![];
|
let mut skip_rpcs = vec![];
|
||||||
|
let mut method_not_available_response = None;
|
||||||
|
|
||||||
let mut watch_consensus_connections = if wait_for_sync {
|
let mut watch_consensus_connections = if wait_for_sync {
|
||||||
Some(self.watch_consensus_connections_sender.subscribe())
|
Some(self.watch_consensus_connections_sender.subscribe())
|
||||||
@ -761,7 +762,6 @@ impl Web3Connections {
|
|||||||
// TODO: is self.conns still right now that we split main and backup servers?
|
// TODO: is self.conns still right now that we split main and backup servers?
|
||||||
// TODO: if a new block arrives, we probably want to reset the skip list
|
// TODO: if a new block arrives, we probably want to reset the skip list
|
||||||
if skip_rpcs.len() == self.conns.len() {
|
if skip_rpcs.len() == self.conns.len() {
|
||||||
// no servers to try
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
match self
|
match self
|
||||||
@ -802,7 +802,7 @@ impl Web3Connections {
|
|||||||
request.id.clone(),
|
request.id.clone(),
|
||||||
) {
|
) {
|
||||||
Ok(response) => {
|
Ok(response) => {
|
||||||
if let Some(error) = &response.error {
|
if let Some(error) = &response.error.as_ref() {
|
||||||
// trace!(?response, "rpc error");
|
// trace!(?response, "rpc error");
|
||||||
|
|
||||||
if let Some(request_metadata) = request_metadata {
|
if let Some(request_metadata) = request_metadata {
|
||||||
@ -843,9 +843,22 @@ impl Web3Connections {
|
|||||||
-32601 => {
|
-32601 => {
|
||||||
let error_msg = error.message.as_str();
|
let error_msg = error.message.as_str();
|
||||||
|
|
||||||
|
// sometimes a provider does not support all rpc methods
|
||||||
|
// we check other connections rather than returning the error
|
||||||
|
// but sometimes the method is something that is actually unsupported,
|
||||||
|
// so we save the response here to return it later
|
||||||
|
|
||||||
|
// some providers look like this
|
||||||
if error_msg.starts_with("the method")
|
if error_msg.starts_with("the method")
|
||||||
&& error_msg.ends_with("is not available")
|
&& error_msg.ends_with("is not available")
|
||||||
{
|
{
|
||||||
|
method_not_available_response = Some(response);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// others look like this
|
||||||
|
if error_msg == "Method not found" {
|
||||||
|
method_not_available_response = Some(response);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -888,6 +901,7 @@ impl Web3Connections {
|
|||||||
{
|
{
|
||||||
// TODO: if there are other servers in synced_connections, we should continue now
|
// TODO: if there are other servers in synced_connections, we should continue now
|
||||||
// wait until retry_at OR synced_connections changes
|
// wait until retry_at OR synced_connections changes
|
||||||
|
trace!("waiting for change in synced servers or retry_at");
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
_ = sleep_until(retry_at) => {
|
_ = sleep_until(retry_at) => {
|
||||||
skip_rpcs.pop();
|
skip_rpcs.pop();
|
||||||
@ -899,7 +913,8 @@ impl Web3Connections {
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
break;
|
sleep_until(retry_at).await;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
OpenRequestResult::NotReady => {
|
OpenRequestResult::NotReady => {
|
||||||
@ -908,18 +923,25 @@ impl Web3Connections {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if wait_for_sync {
|
if wait_for_sync {
|
||||||
|
trace!("waiting for change in synced servers");
|
||||||
// TODO: race here. there might have been a change while we were waiting on the previous server
|
// TODO: race here. there might have been a change while we were waiting on the previous server
|
||||||
self.watch_consensus_connections_sender
|
self.watch_consensus_connections_sender
|
||||||
.subscribe()
|
.subscribe()
|
||||||
.changed()
|
.changed()
|
||||||
.await?;
|
.await?;
|
||||||
} else {
|
} else {
|
||||||
break;
|
// TODO: continue or break?
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(r) = method_not_available_response {
|
||||||
|
// TODO: emit a stat for unsupported methods?
|
||||||
|
return Ok(r);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: do we need this here, or do we do it somewhere else?
|
// TODO: do we need this here, or do we do it somewhere else?
|
||||||
if let Some(request_metadata) = request_metadata {
|
if let Some(request_metadata) = request_metadata {
|
||||||
request_metadata
|
request_metadata
|
||||||
@ -929,9 +951,17 @@ impl Web3Connections {
|
|||||||
|
|
||||||
let num_conns = self.conns.len();
|
let num_conns = self.conns.len();
|
||||||
|
|
||||||
error!("No servers synced ({} known)", num_conns);
|
if skip_rpcs.is_empty() {
|
||||||
|
error!("No servers synced ({} known)", num_conns);
|
||||||
|
|
||||||
Err(anyhow::anyhow!("No servers synced ({} known)", num_conns))
|
Err(anyhow::anyhow!("No servers synced ({} known)", num_conns))
|
||||||
|
} else {
|
||||||
|
Err(anyhow::anyhow!(
|
||||||
|
"{}/{} servers erred",
|
||||||
|
skip_rpcs.len(),
|
||||||
|
num_conns
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// be sure there is a timeout on this or it might loop forever
|
/// be sure there is a timeout on this or it might loop forever
|
||||||
|
Loading…
Reference in New Issue
Block a user