improve rpc filtering
This commit is contained in:
parent
d06aa3b170
commit
519ba473d9
@ -390,41 +390,42 @@ impl Web3Connections {
|
|||||||
) -> anyhow::Result<OpenRequestResult> {
|
) -> anyhow::Result<OpenRequestResult> {
|
||||||
let mut earliest_retry_at = None;
|
let mut earliest_retry_at = None;
|
||||||
|
|
||||||
let min_block_needed = if let Some(min_block_needed) = min_block_needed {
|
let usable_rpcs: Vec<Arc<Web3Connection>> = if let Some(min_block_needed) = min_block_needed
|
||||||
*min_block_needed
|
{
|
||||||
} else {
|
// need a potentially old block. check all the rpcs
|
||||||
match self.head_block_num() {
|
|
||||||
Some(x) => x,
|
|
||||||
None => {
|
|
||||||
trace!("no head block on {:?}", self);
|
|
||||||
return Ok(OpenRequestResult::NotSynced);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
trace!("min block needed: {}", min_block_needed);
|
|
||||||
|
|
||||||
// filter the synced rpcs
|
|
||||||
// TODO: we are going to be checking "has_block_data" a lot now
|
// TODO: we are going to be checking "has_block_data" a lot now
|
||||||
let head_rpcs: Vec<Arc<Web3Connection>> = self
|
self.conns
|
||||||
.synced_connections
|
.values()
|
||||||
|
.filter(|x| !skip.contains(x))
|
||||||
|
.filter(|x| x.has_block_data(min_block_needed))
|
||||||
|
.cloned()
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
// need latest. filter the synced rpcs
|
||||||
|
// TODO: double check has_block_data?
|
||||||
|
self.synced_connections
|
||||||
.load()
|
.load()
|
||||||
.conns
|
.conns
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|x| !skip.contains(x))
|
.filter(|x| !skip.contains(x))
|
||||||
.filter(|x| x.has_block_data(&min_block_needed))
|
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect();
|
.collect()
|
||||||
|
};
|
||||||
|
|
||||||
match head_rpcs.len() {
|
match usable_rpcs.len() {
|
||||||
0 => {
|
0 => {
|
||||||
warn!("no head rpcs: {:?} (skipped {:?})", self, skip);
|
warn!(
|
||||||
|
"no rpcs @ {:?}: {:?} (skipped {:?})",
|
||||||
|
min_block_needed,
|
||||||
|
self.synced_connections.load(),
|
||||||
|
skip.iter().map(|x| &x.name).collect::<Vec<_>>()
|
||||||
|
);
|
||||||
// TODO: what should happen here? automatic retry?
|
// TODO: what should happen here? automatic retry?
|
||||||
// TODO: more detailed error
|
// TODO: more detailed error
|
||||||
return Ok(OpenRequestResult::NotSynced);
|
return Ok(OpenRequestResult::NotSynced);
|
||||||
}
|
}
|
||||||
1 => {
|
1 => {
|
||||||
let rpc = head_rpcs.get(0).expect("len is 1");
|
let rpc = usable_rpcs.get(0).expect("len is 1");
|
||||||
|
|
||||||
// TODO: try or wait for a request handle?
|
// TODO: try or wait for a request handle?
|
||||||
let handle = rpc
|
let handle = rpc
|
||||||
@ -441,7 +442,7 @@ impl Web3Connections {
|
|||||||
let mut minimum = f64::MAX;
|
let mut minimum = f64::MAX;
|
||||||
|
|
||||||
// we sort on a bunch of values. cache them here so that we don't do this math multiple times.
|
// we sort on a bunch of values. cache them here so that we don't do this math multiple times.
|
||||||
let available_request_map: HashMap<_, f64> = head_rpcs
|
let available_request_map: HashMap<_, f64> = usable_rpcs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|rpc| {
|
.map(|rpc| {
|
||||||
// TODO: are active requests what we want? do we want a counter for requests in the last second + any actives longer than that?
|
// TODO: are active requests what we want? do we want a counter for requests in the last second + any actives longer than that?
|
||||||
@ -482,13 +483,14 @@ impl Web3Connections {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let sorted_rpcs = {
|
let sorted_rpcs = {
|
||||||
if head_rpcs.len() == 1 {
|
if usable_rpcs.len() == 1 {
|
||||||
vec![head_rpcs.get(0).expect("there should be 1")]
|
vec![usable_rpcs.get(0).expect("there should be 1")]
|
||||||
} else {
|
} else {
|
||||||
let mut rng = thread_fast_rng::thread_fast_rng();
|
let mut rng = thread_fast_rng::thread_fast_rng();
|
||||||
|
|
||||||
head_rpcs
|
// TODO: sort or weight the non-archive nodes to be first
|
||||||
.choose_multiple_weighted(&mut rng, head_rpcs.len(), |rpc| {
|
usable_rpcs
|
||||||
|
.choose_multiple_weighted(&mut rng, usable_rpcs.len(), |rpc| {
|
||||||
*available_request_map
|
*available_request_map
|
||||||
.get(rpc)
|
.get(rpc)
|
||||||
.expect("rpc should always be in the weight map")
|
.expect("rpc should always be in the weight map")
|
||||||
@ -709,8 +711,6 @@ impl Web3Connections {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
OpenRequestResult::NotSynced => {
|
OpenRequestResult::NotSynced => {
|
||||||
warn!("No synced servers! {:?}", self);
|
|
||||||
|
|
||||||
if let Some(request_metadata) = request_metadata {
|
if let Some(request_metadata) = request_metadata {
|
||||||
request_metadata.no_servers.fetch_add(1, Ordering::Release);
|
request_metadata.no_servers.fetch_add(1, Ordering::Release);
|
||||||
}
|
}
|
||||||
@ -730,6 +730,8 @@ impl Web3Connections {
|
|||||||
.store(true, Ordering::Release);
|
.store(true, Ordering::Release);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
warn!("No synced servers! {:?}", self.synced_connections.load());
|
||||||
|
|
||||||
// TODO: what error code? 502?
|
// TODO: what error code? 502?
|
||||||
Err(anyhow::anyhow!("all {} tries exhausted", skip_rpcs.len()))
|
Err(anyhow::anyhow!("all {} tries exhausted", skip_rpcs.len()))
|
||||||
}
|
}
|
||||||
@ -996,18 +998,14 @@ mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// best_synced_backend_connection requires servers to be synced with the head block
|
// best_synced_backend_connection requires servers to be synced with the head block
|
||||||
assert!(matches!(
|
let x = conns
|
||||||
conns
|
.best_synced_backend_connection(&authorization, None, &[], None)
|
||||||
.best_synced_backend_connection(
|
|
||||||
&authorization,
|
|
||||||
None,
|
|
||||||
&[],
|
|
||||||
lagged_block.number.as_ref()
|
|
||||||
)
|
|
||||||
.await
|
.await
|
||||||
.unwrap(),
|
.unwrap();
|
||||||
OpenRequestResult::NotSynced
|
|
||||||
));
|
dbg!(&x);
|
||||||
|
|
||||||
|
assert!(matches!(x, OpenRequestResult::NotSynced));
|
||||||
|
|
||||||
// add lagged blocks to the conns. both servers should be allowed
|
// add lagged blocks to the conns. both servers should be allowed
|
||||||
conns.save_block(&lagged_block, true).await.unwrap();
|
conns.save_block(&lagged_block, true).await.unwrap();
|
||||||
|
Loading…
Reference in New Issue
Block a user