From df668a5dfdee1d90013ba2edce0ce2a2e398869a Mon Sep 17 00:00:00 2001 From: Bryan Stitt Date: Wed, 15 Feb 2023 11:42:25 -0800 Subject: [PATCH] add time to idle to more caches --- web3_proxy/src/app/mod.rs | 9 ++++++++- web3_proxy/src/rpcs/many.rs | 22 ++++++++++------------ 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/web3_proxy/src/app/mod.rs b/web3_proxy/src/app/mod.rs index bcb54937..303ea187 100644 --- a/web3_proxy/src/app/mod.rs +++ b/web3_proxy/src/app/mod.rs @@ -556,9 +556,12 @@ impl Web3ProxyApp { // TODO: ttl on this? or is max_capacity fine? let pending_transactions = Cache::builder() .max_capacity(10_000) + // TODO: different chains might handle this differently + // TODO: what should we set? 5 minutes is arbitrary. the nodes themselves hold onto transactions for much longer + .time_to_idle(Duration::from_secs(300)) .build_with_hasher(hashbrown::hash_map::DefaultHashBuilder::default()); - // keep 1GB of blocks in the cache + // keep 1GB/5 minutes of blocks in the cache // TODO: limits from config // these blocks don't have full transactions, but they do have rather variable amounts of transaction hashes // TODO: how can we do the weigher better? @@ -568,6 +571,8 @@ impl Web3ProxyApp { // TODO: is this good enough? 1 + v.block.transactions.len().try_into().unwrap_or(u32::MAX) }) + // TODO: what should we set? 5 minutes is arbitrary. the nodes themselves hold onto transactions for much longer + .time_to_idle(Duration::from_secs(300)) .build_with_hasher(hashbrown::hash_map::DefaultHashBuilder::default()); // connect to the load balanced rpcs @@ -690,6 +695,8 @@ impl Web3ProxyApp { u32::MAX } }) + // TODO: what should we set? 10 minutes is arbitrary. the nodes themselves hold onto transactions for much longer + .time_to_idle(Duration::from_secs(600)) .build_with_hasher(hashbrown::hash_map::DefaultHashBuilder::default()); // all the users are the same size, so no need for a weigher diff --git a/web3_proxy/src/rpcs/many.rs b/web3_proxy/src/rpcs/many.rs index c449b241..19958016 100644 --- a/web3_proxy/src/rpcs/many.rs +++ b/web3_proxy/src/rpcs/many.rs @@ -20,6 +20,7 @@ use itertools::Itertools; use log::{debug, error, info, trace, warn, Level}; use migration::sea_orm::DatabaseConnection; use moka::future::{Cache, ConcurrentCacheExt}; +use ordered_float::OrderedFloat; use serde::ser::{SerializeStruct, Serializer}; use serde::Serialize; use serde_json::json; @@ -572,7 +573,9 @@ impl Web3Rpcs { // pick the first two and try the one with the lower rpc.latency.ewma // TODO: chunks or tuple windows? for (rpc_a, rpc_b) in usable_rpcs.into_iter().circular_tuple_windows() { - let best_rpc = min_by_key(rpc_a, rpc_b, |x| x.latency.request_ewma); + let best_rpc = min_by_key(rpc_a, rpc_b, |x| { + OrderedFloat(x.request_latency.read().ewma.value()) + }); // just because it has lower latency doesn't mean we are sure to get a connection match best_rpc.try_request_handle(authorization, None).await { @@ -1154,18 +1157,19 @@ impl Serialize for Web3Rpcs { /// sort by block number (descending) and tier (ascending) /// TODO: should this be moved into a `impl Web3Rpc`? +/// TODO: i think we still have sorts scattered around the code that should use this /// TODO: take AsRef or something like that? We don't need an Arc here -fn rpc_sync_status_sort_key(x: &Arc) -> (u64, u64, u32) { - let reversed_head_block = u64::MAX +fn rpc_sync_status_sort_key(x: &Arc) -> (U64, u64, OrderedFloat) { + let reversed_head_block = U64::MAX - x.head_block .read() .as_ref() - .map(|x| x.number().as_u64()) - .unwrap_or(0); + .map(|x| *x.number()) + .unwrap_or_default(); let tier = x.tier; - let request_ewma = x.latency.request_ewma; + let request_ewma = OrderedFloat(x.request_latency.read().ewma.value()); (reversed_head_block, tier, request_ewma) } @@ -1340,13 +1344,10 @@ mod tests { watch_consensus_head_receiver: None, watch_consensus_rpcs_sender, pending_transactions: Cache::builder() - .max_capacity(10_000) .build_with_hasher(hashbrown::hash_map::DefaultHashBuilder::default()), block_hashes: Cache::builder() - .max_capacity(10_000) .build_with_hasher(hashbrown::hash_map::DefaultHashBuilder::default()), block_numbers: Cache::builder() - .max_capacity(10_000) .build_with_hasher(hashbrown::hash_map::DefaultHashBuilder::default()), // TODO: test max_block_age? max_block_age: None, @@ -1541,13 +1542,10 @@ mod tests { watch_consensus_head_receiver: None, watch_consensus_rpcs_sender, pending_transactions: Cache::builder() - .max_capacity(10) .build_with_hasher(hashbrown::hash_map::DefaultHashBuilder::default()), block_hashes: Cache::builder() - .max_capacity(10) .build_with_hasher(hashbrown::hash_map::DefaultHashBuilder::default()), block_numbers: Cache::builder() - .max_capacity(10) .build_with_hasher(hashbrown::hash_map::DefaultHashBuilder::default()), min_head_rpcs: 1, min_sum_soft_limit: 4_000,