simplify max item weight by having the weigher send MAX for big things
This commit is contained in:
parent
1ec0f14144
commit
5d9365449f
34
Cargo.lock
generated
34
Cargo.lock
generated
@ -1813,8 +1813,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ethers"
|
name = "ethers"
|
||||||
version = "2.0.7"
|
version = "2.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/llamanodes/ethers-rs/?rev=eb68f5d60850008cd302762bd3a5a4bdcfecc713#eb68f5d60850008cd302762bd3a5a4bdcfecc713"
|
||||||
checksum = "2a58ce802c65cf3d0756dee5a61094a92cde53c1583b246e9ee5b37226c7fc15"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ethers-addressbook",
|
"ethers-addressbook",
|
||||||
"ethers-contract",
|
"ethers-contract",
|
||||||
@ -1829,8 +1828,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ethers-addressbook"
|
name = "ethers-addressbook"
|
||||||
version = "2.0.7"
|
version = "2.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/llamanodes/ethers-rs/?rev=eb68f5d60850008cd302762bd3a5a4bdcfecc713#eb68f5d60850008cd302762bd3a5a4bdcfecc713"
|
||||||
checksum = "7b856b7b8ff5c961093cb8efe151fbcce724b451941ce20781de11a531ccd578"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ethers-core",
|
"ethers-core",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
@ -1841,13 +1839,13 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ethers-contract"
|
name = "ethers-contract"
|
||||||
version = "2.0.7"
|
version = "2.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/llamanodes/ethers-rs/?rev=eb68f5d60850008cd302762bd3a5a4bdcfecc713#eb68f5d60850008cd302762bd3a5a4bdcfecc713"
|
||||||
checksum = "e066a0d9cfc70c454672bf16bb433b0243427420076dc5b2f49c448fb5a10628"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ethers-contract-abigen",
|
"ethers-contract-abigen",
|
||||||
"ethers-contract-derive",
|
"ethers-contract-derive",
|
||||||
"ethers-core",
|
"ethers-core",
|
||||||
"ethers-providers",
|
"ethers-providers",
|
||||||
|
"ethers-signers",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"hex",
|
"hex",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
@ -1860,8 +1858,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ethers-contract-abigen"
|
name = "ethers-contract-abigen"
|
||||||
version = "2.0.7"
|
version = "2.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/llamanodes/ethers-rs/?rev=eb68f5d60850008cd302762bd3a5a4bdcfecc713#eb68f5d60850008cd302762bd3a5a4bdcfecc713"
|
||||||
checksum = "c113e3e86b6bc16d98484b2c3bb2d01d6fed9f489fe2e592e5cc87c3024d616b"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"Inflector",
|
"Inflector",
|
||||||
"dunce",
|
"dunce",
|
||||||
@ -1884,8 +1881,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ethers-contract-derive"
|
name = "ethers-contract-derive"
|
||||||
version = "2.0.7"
|
version = "2.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/llamanodes/ethers-rs/?rev=eb68f5d60850008cd302762bd3a5a4bdcfecc713#eb68f5d60850008cd302762bd3a5a4bdcfecc713"
|
||||||
checksum = "8c3fb5adee25701c79ec58fcf2c63594cd8829bc9ad6037ff862d5a111101ed2"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"Inflector",
|
"Inflector",
|
||||||
"ethers-contract-abigen",
|
"ethers-contract-abigen",
|
||||||
@ -1900,8 +1896,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ethers-core"
|
name = "ethers-core"
|
||||||
version = "2.0.7"
|
version = "2.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/llamanodes/ethers-rs/?rev=eb68f5d60850008cd302762bd3a5a4bdcfecc713#eb68f5d60850008cd302762bd3a5a4bdcfecc713"
|
||||||
checksum = "6da5fa198af0d3be20c19192df2bd9590b92ce09a8421e793bec8851270f1b05"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayvec",
|
"arrayvec",
|
||||||
"bytes",
|
"bytes",
|
||||||
@ -1930,8 +1925,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ethers-etherscan"
|
name = "ethers-etherscan"
|
||||||
version = "2.0.7"
|
version = "2.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/llamanodes/ethers-rs/?rev=eb68f5d60850008cd302762bd3a5a4bdcfecc713#eb68f5d60850008cd302762bd3a5a4bdcfecc713"
|
||||||
checksum = "84ebb401ba97c6f5af278c2c9936c4546cad75dec464b439ae6df249906f4caa"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ethers-core",
|
"ethers-core",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
@ -1945,8 +1939,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ethers-middleware"
|
name = "ethers-middleware"
|
||||||
version = "2.0.7"
|
version = "2.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/llamanodes/ethers-rs/?rev=eb68f5d60850008cd302762bd3a5a4bdcfecc713#eb68f5d60850008cd302762bd3a5a4bdcfecc713"
|
||||||
checksum = "740f4a773c19dd6d6a68c8c2e0996c096488d38997d524e21dc612c55da3bd24"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"auto_impl",
|
"auto_impl",
|
||||||
@ -1972,8 +1965,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ethers-providers"
|
name = "ethers-providers"
|
||||||
version = "2.0.7"
|
version = "2.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/llamanodes/ethers-rs/?rev=eb68f5d60850008cd302762bd3a5a4bdcfecc713#eb68f5d60850008cd302762bd3a5a4bdcfecc713"
|
||||||
checksum = "56b498fd2a6c019d023e43e83488cd1fb0721f299055975aa6bac8dbf1e95f2c"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"auto_impl",
|
"auto_impl",
|
||||||
@ -2009,8 +2001,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ethers-signers"
|
name = "ethers-signers"
|
||||||
version = "2.0.7"
|
version = "2.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/llamanodes/ethers-rs/?rev=eb68f5d60850008cd302762bd3a5a4bdcfecc713#eb68f5d60850008cd302762bd3a5a4bdcfecc713"
|
||||||
checksum = "02c4b7e15f212fa7cc2e1251868320221d4ff77a3d48068e69f47ce1c491df2d"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"coins-bip32",
|
"coins-bip32",
|
||||||
@ -2028,8 +2019,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ethers-solc"
|
name = "ethers-solc"
|
||||||
version = "2.0.7"
|
version = "2.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/llamanodes/ethers-rs/?rev=eb68f5d60850008cd302762bd3a5a4bdcfecc713#eb68f5d60850008cd302762bd3a5a4bdcfecc713"
|
||||||
checksum = "a81c89f121595cf8959e746045bb8b25a6a38d72588561e1a3b7992fc213f674"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"dunce",
|
"dunce",
|
||||||
|
@ -10,8 +10,9 @@ path = "src/mod.rs"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
ethers = { git = "https://github.com/llamanodes/ethers-rs/", rev = "eb68f5d60850008cd302762bd3a5a4bdcfecc713", default-features = false }
|
||||||
|
|
||||||
sea-orm = "0.11.3"
|
sea-orm = "0.11.3"
|
||||||
serde = "1.0.164"
|
serde = "1.0.164"
|
||||||
uuid = "1.3.4"
|
|
||||||
ethers = "2.0.7"
|
|
||||||
ulid = "1.0.0"
|
ulid = "1.0.0"
|
||||||
|
uuid = "1.3.4"
|
||||||
|
@ -6,8 +6,9 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
ethers = "2.0.7"
|
ethers = { git = "https://github.com/llamanodes/ethers-rs/", rev = "eb68f5d60850008cd302762bd3a5a4bdcfecc713", default-features = false }
|
||||||
|
|
||||||
glob = "0.3.1"
|
glob = "0.3.1"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ethers = "2.0.7"
|
ethers = { git = "https://github.com/llamanodes/ethers-rs/", rev = "eb68f5d60850008cd302762bd3a5a4bdcfecc713", default-features = false }
|
||||||
|
@ -22,6 +22,7 @@ migration = { path = "../migration" }
|
|||||||
payment-contracts = { path = "../payment-contracts" }
|
payment-contracts = { path = "../payment-contracts" }
|
||||||
redis-rate-limiter = { path = "../redis-rate-limiter" }
|
redis-rate-limiter = { path = "../redis-rate-limiter" }
|
||||||
|
|
||||||
|
ethers = { git = "https://github.com/llamanodes/ethers-rs/", rev = "eb68f5d60850008cd302762bd3a5a4bdcfecc713", default-features = false, features = ["rustls", "ws"] }
|
||||||
influxdb2 = { git = "https://github.com/llamanodes/influxdb2", features = ["rustls"], rev = "1e5577e14150797584f5ed0ea7aba0bd68f0a678" }
|
influxdb2 = { git = "https://github.com/llamanodes/influxdb2", features = ["rustls"], rev = "1e5577e14150797584f5ed0ea7aba0bd68f0a678" }
|
||||||
influxdb2-structmap = { git = "https://github.com/llamanodes/influxdb2/", rev = "1e5577e14150797584f5ed0ea7aba0bd68f0a678"}
|
influxdb2-structmap = { git = "https://github.com/llamanodes/influxdb2/", rev = "1e5577e14150797584f5ed0ea7aba0bd68f0a678"}
|
||||||
|
|
||||||
@ -50,7 +51,6 @@ counter = "0.5.7"
|
|||||||
derive_more = "0.99.17"
|
derive_more = "0.99.17"
|
||||||
env_logger = "0.10.0"
|
env_logger = "0.10.0"
|
||||||
ethbloom = "0.13.0"
|
ethbloom = "0.13.0"
|
||||||
ethers = { version = "2.0.7", default-features = false, features = ["rustls", "ws"] }
|
|
||||||
ewma = "0.1.1"
|
ewma = "0.1.1"
|
||||||
fdlimit = "0.2.1"
|
fdlimit = "0.2.1"
|
||||||
flume = "0.10.14"
|
flume = "0.10.14"
|
||||||
|
@ -13,7 +13,7 @@ use crate::jsonrpc::{
|
|||||||
};
|
};
|
||||||
use crate::relational_db::{get_db, get_migrated_db, DatabaseConnection, DatabaseReplica};
|
use crate::relational_db::{get_db, get_migrated_db, DatabaseConnection, DatabaseReplica};
|
||||||
use crate::response_cache::{
|
use crate::response_cache::{
|
||||||
json_rpc_response_weigher, JsonRpcQueryCacheKey, JsonRpcResponseCache, JsonRpcResponseEnum,
|
JsonRpcQueryCacheKey, JsonRpcResponseCache, JsonRpcResponseEnum, JsonRpcResponseWeigher,
|
||||||
};
|
};
|
||||||
use crate::rpcs::blockchain::Web3ProxyBlock;
|
use crate::rpcs::blockchain::Web3ProxyBlock;
|
||||||
use crate::rpcs::consensus::ConsensusWeb3Rpcs;
|
use crate::rpcs::consensus::ConsensusWeb3Rpcs;
|
||||||
@ -43,7 +43,6 @@ use log::{error, info, trace, warn, Level};
|
|||||||
use migration::sea_orm::prelude::Decimal;
|
use migration::sea_orm::prelude::Decimal;
|
||||||
use migration::sea_orm::{DatabaseTransaction, EntityTrait, PaginatorTrait, TransactionTrait};
|
use migration::sea_orm::{DatabaseTransaction, EntityTrait, PaginatorTrait, TransactionTrait};
|
||||||
use moka::future::{Cache, CacheBuilder};
|
use moka::future::{Cache, CacheBuilder};
|
||||||
use parking_lot::Mutex;
|
|
||||||
use redis_rate_limiter::redis::AsyncCommands;
|
use redis_rate_limiter::redis::AsyncCommands;
|
||||||
use redis_rate_limiter::{redis, DeadpoolRuntime, RedisConfig, RedisPool, RedisRateLimiter};
|
use redis_rate_limiter::{redis, DeadpoolRuntime, RedisConfig, RedisPool, RedisRateLimiter};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
@ -516,13 +515,15 @@ impl Web3ProxyApp {
|
|||||||
// responses can be very different in sizes, so this is a cache with a max capacity and a weigher
|
// responses can be very different in sizes, so this is a cache with a max capacity and a weigher
|
||||||
// TODO: we should emit stats to calculate a more accurate expected cache size
|
// TODO: we should emit stats to calculate a more accurate expected cache size
|
||||||
// TODO: do we actually want a TTL on this?
|
// TODO: do we actually want a TTL on this?
|
||||||
// TODO: configurable max item weight
|
// TODO: configurable max item weight insted of hard coding to .1% of the cache?
|
||||||
// TODO: resize the cache automatically
|
let jsonrpc_weigher =
|
||||||
|
JsonRpcResponseWeigher((top_config.app.response_cache_max_bytes / 1000) as u32);
|
||||||
|
|
||||||
let jsonrpc_response_cache: JsonRpcResponseCache =
|
let jsonrpc_response_cache: JsonRpcResponseCache =
|
||||||
CacheBuilder::new(top_config.app.response_cache_max_bytes)
|
CacheBuilder::new(top_config.app.response_cache_max_bytes)
|
||||||
.name("jsonrpc_response_cache")
|
.name("jsonrpc_response_cache")
|
||||||
.time_to_idle(Duration::from_secs(3600))
|
.time_to_idle(Duration::from_secs(3600))
|
||||||
.weigher(json_rpc_response_weigher)
|
.weigher(move |k, v| jsonrpc_weigher.weigh(k, v))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// TODO: how should we handle hitting this max?
|
// TODO: how should we handle hitting this max?
|
||||||
@ -1703,17 +1704,13 @@ impl Web3ProxyApp {
|
|||||||
if let Some(cache_key) = cache_key {
|
if let Some(cache_key) = cache_key {
|
||||||
let from_block_num = cache_key.from_block_num();
|
let from_block_num = cache_key.from_block_num();
|
||||||
let to_block_num = cache_key.to_block_num();
|
let to_block_num = cache_key.to_block_num();
|
||||||
let cache_errors = cache_key.cache_errors();
|
let cache_jsonrpc_errors = cache_key.cache_errors();
|
||||||
|
|
||||||
// moka makes us do annoying things with arcs
|
// TODO: try to fetch out of s3
|
||||||
enum CacheError {
|
|
||||||
NotCached(JsonRpcResponseEnum<Arc<RawValue>>),
|
|
||||||
Error(Arc<Web3ProxyError>),
|
|
||||||
}
|
|
||||||
|
|
||||||
let x = self
|
self
|
||||||
.jsonrpc_response_cache
|
.jsonrpc_response_cache
|
||||||
.try_get_with::<_, Mutex<CacheError>>(cache_key.hash(), async {
|
.try_get_with::<_, Web3ProxyError>(cache_key.hash(), async {
|
||||||
let response_data = timeout(
|
let response_data = timeout(
|
||||||
duration,
|
duration,
|
||||||
self.balanced_rpcs
|
self.balanced_rpcs
|
||||||
@ -1725,34 +1722,20 @@ impl Web3ProxyApp {
|
|||||||
to_block_num.as_ref(),
|
to_block_num.as_ref(),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.await
|
.await?;
|
||||||
.map_err(|x| Mutex::new(CacheError::Error(Arc::new(Web3ProxyError::from(x)))))?;
|
|
||||||
|
|
||||||
// TODO: i think response data should be Arc<JsonRpcResponseEnum<Box<RawValue>>>, but that's more work
|
if !cache_jsonrpc_errors && let Err(err) = response_data {
|
||||||
let response_data: JsonRpcResponseEnum<Arc<RawValue>> = response_data.try_into()
|
// if we are not supposed to cache jsonrpc errors,
|
||||||
.map_err(|x| Mutex::new(CacheError::Error(Arc::new(x))))?;
|
// then we must not convert Provider errors into a JsonRpcResponseEnum
|
||||||
|
// return all the errors now. moka will not cache Err results
|
||||||
// TODO: read max size from the config
|
Err(err)
|
||||||
if response_data.num_bytes() as u64 > self.config.response_cache_max_bytes / 1000 {
|
|
||||||
Err(Mutex::new(CacheError::NotCached(response_data)))
|
|
||||||
} else if matches!(response_data, JsonRpcResponseEnum::Result { .. }) || cache_errors {
|
|
||||||
Ok(response_data)
|
|
||||||
} else {
|
} else {
|
||||||
Err(Mutex::new(CacheError::NotCached(response_data)))
|
let response_data: JsonRpcResponseEnum<Arc<RawValue>> = response_data.try_into()?;
|
||||||
}
|
|
||||||
}).await;
|
|
||||||
|
|
||||||
match x {
|
// TODO: response data should maybe be Arc<JsonRpcResponseEnum<Box<RawValue>>>, but that's more work
|
||||||
Ok(x) => x,
|
Ok(response_data)
|
||||||
Err(arc_err) => {
|
|
||||||
let locked = arc_err.lock();
|
|
||||||
|
|
||||||
match &*locked {
|
|
||||||
CacheError::Error(err) => return Err(Web3ProxyError::Arc(err.clone())),
|
|
||||||
CacheError::NotCached(x) => x.clone(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}).await?
|
||||||
} else {
|
} else {
|
||||||
let x = timeout(
|
let x = timeout(
|
||||||
duration,
|
duration,
|
||||||
|
@ -214,7 +214,7 @@ impl Web3ProxyError {
|
|||||||
}
|
}
|
||||||
Self::BadResponse(err) => {
|
Self::BadResponse(err) => {
|
||||||
// TODO: think about this one more. ankr gives us this because ethers fails to parse responses without an id
|
// TODO: think about this one more. ankr gives us this because ethers fails to parse responses without an id
|
||||||
debug!("BAD_RESPONSE: {}", err);
|
debug!("BAD_RESPONSE: {:?}", err);
|
||||||
(
|
(
|
||||||
StatusCode::INTERNAL_SERVER_ERROR,
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
JsonRpcErrorData {
|
JsonRpcErrorData {
|
||||||
|
@ -314,7 +314,10 @@ impl JsonRpcForwardedResponse {
|
|||||||
data = err.data.clone();
|
data = err.data.clone();
|
||||||
} else if let Some(err) = err.as_serde_error() {
|
} else if let Some(err) = err.as_serde_error() {
|
||||||
// this is not an rpc error. keep it as an error
|
// this is not an rpc error. keep it as an error
|
||||||
return Err(Web3ProxyError::BadResponse(err.to_string().into()));
|
// TODO: ankr gives us "rate limited" but ethers fails to parse because it tries to require id even though its optional
|
||||||
|
return Err(Web3ProxyError::BadResponse(
|
||||||
|
format!("parse error: {}", err).into(),
|
||||||
|
));
|
||||||
} else {
|
} else {
|
||||||
return Err(anyhow::anyhow!("unexpected ethers error! {:?}", err).into());
|
return Err(anyhow::anyhow!("unexpected ethers error! {:?}", err).into());
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#![feature(let_chains)]
|
||||||
#![feature(trait_alias)]
|
#![feature(trait_alias)]
|
||||||
|
|
||||||
pub mod admin_queries;
|
pub mod admin_queries;
|
||||||
|
@ -226,60 +226,65 @@ impl TryFrom<ProviderError> for JsonRpcErrorData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn json_rpc_response_weigher<K, R>(_key: &K, value: &JsonRpcResponseEnum<R>) -> u32 {
|
/// The inner u32 is the maximum weight per item
|
||||||
value.num_bytes()
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct JsonRpcResponseWeigher(pub u32);
|
||||||
|
|
||||||
|
impl JsonRpcResponseWeigher {
|
||||||
|
pub fn weigh<K, R>(&self, _key: &K, value: &JsonRpcResponseEnum<R>) -> u32 {
|
||||||
|
let x = value.num_bytes();
|
||||||
|
|
||||||
|
if x > self.0 {
|
||||||
|
// return max. the item may start to be inserted into the cache, but it will be immediatly removed
|
||||||
|
u32::MAX
|
||||||
|
} else {
|
||||||
|
x
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::JsonRpcResponseEnum;
|
use super::JsonRpcResponseEnum;
|
||||||
use crate::response_cache::json_rpc_response_weigher;
|
use crate::response_cache::JsonRpcResponseWeigher;
|
||||||
|
use moka::future::{Cache, CacheBuilder, ConcurrentCacheExt};
|
||||||
use serde_json::value::RawValue;
|
use serde_json::value::RawValue;
|
||||||
use std::sync::Arc;
|
use std::{sync::Arc, time::Duration};
|
||||||
|
|
||||||
#[tokio::test(start_paused = true)]
|
#[tokio::test(start_paused = true)]
|
||||||
async fn test_json_rpc_query_weigher() {
|
async fn test_json_rpc_query_weigher() {
|
||||||
let max_item_weight = 200;
|
let max_item_weight = 200;
|
||||||
let weight_capacity = 1_000;
|
let weight_capacity = 1_000;
|
||||||
|
|
||||||
// let test_cache: Cache<u32, JsonRpcResponseEnum<Arc<RawValue>>> =
|
let weigher = JsonRpcResponseWeigher(max_item_weight);
|
||||||
// CacheBuilder::new(weight_capacity)
|
|
||||||
// .weigher(json_rpc_response_weigher)
|
|
||||||
// .time_to_live(Duration::from_secs(2))
|
|
||||||
// .build();
|
|
||||||
|
|
||||||
let small_data: JsonRpcResponseEnum<Arc<RawValue>> = JsonRpcResponseEnum::Result {
|
let small_data: JsonRpcResponseEnum<Arc<RawValue>> = JsonRpcResponseEnum::Result {
|
||||||
value: Box::<RawValue>::default().into(),
|
value: Box::<RawValue>::default().into(),
|
||||||
num_bytes: max_item_weight / 2,
|
num_bytes: max_item_weight / 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(weigher.weigh(&(), &small_data), max_item_weight / 2);
|
||||||
json_rpc_response_weigher(&(), &small_data),
|
|
||||||
max_item_weight / 2
|
|
||||||
);
|
|
||||||
|
|
||||||
let max_sized_data: JsonRpcResponseEnum<Arc<RawValue>> = JsonRpcResponseEnum::Result {
|
let max_sized_data: JsonRpcResponseEnum<Arc<RawValue>> = JsonRpcResponseEnum::Result {
|
||||||
value: Box::<RawValue>::default().into(),
|
value: Box::<RawValue>::default().into(),
|
||||||
num_bytes: max_item_weight,
|
num_bytes: max_item_weight,
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(weigher.weigh(&(), &max_sized_data), max_item_weight);
|
||||||
json_rpc_response_weigher(&(), &max_sized_data),
|
|
||||||
max_item_weight
|
|
||||||
);
|
|
||||||
|
|
||||||
let oversized_data: JsonRpcResponseEnum<Arc<RawValue>> = JsonRpcResponseEnum::Result {
|
let oversized_data: JsonRpcResponseEnum<Arc<RawValue>> = JsonRpcResponseEnum::Result {
|
||||||
value: Box::<RawValue>::default().into(),
|
value: Box::<RawValue>::default().into(),
|
||||||
num_bytes: max_item_weight * 2,
|
num_bytes: max_item_weight * 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(weigher.weigh(&(), &oversized_data), u32::MAX);
|
||||||
json_rpc_response_weigher(&(), &oversized_data),
|
|
||||||
max_item_weight * 2
|
let test_cache: Cache<u32, JsonRpcResponseEnum<Arc<RawValue>>> =
|
||||||
);
|
CacheBuilder::new(weight_capacity)
|
||||||
|
.weigher(move |k, v| weigher.weigh(k, v))
|
||||||
|
.time_to_live(Duration::from_secs(2))
|
||||||
|
.build();
|
||||||
|
|
||||||
// TODO: helper for inserts that does size checking
|
|
||||||
/*
|
|
||||||
test_cache.insert(0, small_data).await;
|
test_cache.insert(0, small_data).await;
|
||||||
|
|
||||||
test_cache.get(&0).unwrap();
|
test_cache.get(&0).unwrap();
|
||||||
@ -289,12 +294,18 @@ mod tests {
|
|||||||
test_cache.get(&0).unwrap();
|
test_cache.get(&0).unwrap();
|
||||||
test_cache.get(&1).unwrap();
|
test_cache.get(&1).unwrap();
|
||||||
|
|
||||||
// TODO: this will currently work! need to wrap moka cache in a checked insert
|
|
||||||
test_cache.insert(2, oversized_data).await;
|
test_cache.insert(2, oversized_data).await;
|
||||||
|
|
||||||
test_cache.get(&0).unwrap();
|
test_cache.get(&0).unwrap();
|
||||||
test_cache.get(&1).unwrap();
|
test_cache.get(&1).unwrap();
|
||||||
|
|
||||||
|
// oversized data will be in the cache temporarily (it should just be an arc though, so that should be fine)
|
||||||
|
test_cache.get(&2).unwrap();
|
||||||
|
|
||||||
|
// sync should do necessary cleanup
|
||||||
|
test_cache.sync();
|
||||||
|
|
||||||
|
// now it should be empty
|
||||||
assert!(test_cache.get(&2).is_none());
|
assert!(test_cache.get(&2).is_none());
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user