Arc instead of Box for better caching
This commit is contained in:
parent
c2a3a4a0a9
commit
4f7144abc6
@ -1181,7 +1181,7 @@ impl Web3ProxyApp {
|
|||||||
mut params: serde_json::Value,
|
mut params: serde_json::Value,
|
||||||
head_block_num: Option<U64>,
|
head_block_num: Option<U64>,
|
||||||
request_metadata: &Arc<RequestMetadata>,
|
request_metadata: &Arc<RequestMetadata>,
|
||||||
) -> Web3ProxyResult<JsonRpcResponseEnum<Box<RawValue>>> {
|
) -> Web3ProxyResult<JsonRpcResponseEnum<Arc<RawValue>>> {
|
||||||
// TODO: don't clone into a new string?
|
// TODO: don't clone into a new string?
|
||||||
let request_method = method.to_string();
|
let request_method = method.to_string();
|
||||||
|
|
||||||
@ -1189,7 +1189,7 @@ impl Web3ProxyApp {
|
|||||||
|
|
||||||
// TODO: serve net_version without querying the backend
|
// TODO: serve net_version without querying the backend
|
||||||
// TODO: don't force RawValue
|
// TODO: don't force RawValue
|
||||||
let response_data: JsonRpcResponseEnum<Box<RawValue>> = match request_method.as_ref() {
|
let response_data: JsonRpcResponseEnum<Arc<RawValue>> = match request_method.as_ref() {
|
||||||
// lots of commands are blocked
|
// lots of commands are blocked
|
||||||
method @ ("db_getHex"
|
method @ ("db_getHex"
|
||||||
| "db_getString"
|
| "db_getString"
|
||||||
@ -1701,14 +1701,14 @@ impl Web3ProxyApp {
|
|||||||
|
|
||||||
match self
|
match self
|
||||||
.jsonrpc_response_cache
|
.jsonrpc_response_cache
|
||||||
.get_value_or_guard_async(cache_key).await
|
.get_value_or_guard_async(cache_key.hash()).await
|
||||||
{
|
{
|
||||||
Ok(x) => x,
|
Ok(x) => x,
|
||||||
Err(x) => {
|
Err(x) => {
|
||||||
let response_data = timeout(
|
let response_data = timeout(
|
||||||
duration,
|
duration,
|
||||||
self.balanced_rpcs
|
self.balanced_rpcs
|
||||||
.try_proxy_connection::<_, Box<RawValue>>(
|
.try_proxy_connection::<_, Arc<RawValue>>(
|
||||||
method,
|
method,
|
||||||
¶ms,
|
¶ms,
|
||||||
Some(request_metadata),
|
Some(request_metadata),
|
||||||
@ -1718,7 +1718,7 @@ impl Web3ProxyApp {
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let response_data: JsonRpcResponseEnum<Box<RawValue>> = response_data.try_into()?;
|
let response_data: JsonRpcResponseEnum<Arc<RawValue>> = response_data.try_into()?;
|
||||||
|
|
||||||
if matches!(response_data, JsonRpcResponseEnum::Result { .. }) || cache_errors {
|
if matches!(response_data, JsonRpcResponseEnum::Result { .. }) || cache_errors {
|
||||||
// TODO: convert the Box<RawValue> to an Arc<RawValue>?
|
// TODO: convert the Box<RawValue> to an Arc<RawValue>?
|
||||||
@ -1732,7 +1732,7 @@ impl Web3ProxyApp {
|
|||||||
let x = timeout(
|
let x = timeout(
|
||||||
duration,
|
duration,
|
||||||
self.balanced_rpcs
|
self.balanced_rpcs
|
||||||
.try_proxy_connection::<_, Box<RawValue>>(
|
.try_proxy_connection::<_, Arc<RawValue>>(
|
||||||
method,
|
method,
|
||||||
¶ms,
|
¶ms,
|
||||||
Some(request_metadata),
|
Some(request_metadata),
|
||||||
|
@ -8,6 +8,7 @@ use serde_json::json;
|
|||||||
use serde_json::value::{to_raw_value, RawValue};
|
use serde_json::value::{to_raw_value, RawValue};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub trait JsonRpcParams = Clone + fmt::Debug + serde::Serialize + Send + Sync + 'static;
|
pub trait JsonRpcParams = Clone + fmt::Debug + serde::Serialize + Send + Sync + 'static;
|
||||||
pub trait JsonRpcResultData = serde::Serialize + serde::de::DeserializeOwned + fmt::Debug + Send;
|
pub trait JsonRpcResultData = serde::Serialize + serde::de::DeserializeOwned + fmt::Debug + Send;
|
||||||
@ -234,7 +235,7 @@ pub struct JsonRpcForwardedResponse {
|
|||||||
pub jsonrpc: &'static str,
|
pub jsonrpc: &'static str,
|
||||||
pub id: Box<RawValue>,
|
pub id: Box<RawValue>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub result: Option<Box<RawValue>>,
|
pub result: Option<Arc<RawValue>>,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub error: Option<JsonRpcErrorData>,
|
pub error: Option<JsonRpcErrorData>,
|
||||||
}
|
}
|
||||||
@ -279,7 +280,7 @@ impl JsonRpcForwardedResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_raw_response(result: Box<RawValue>, id: Box<RawValue>) -> Self {
|
pub fn from_raw_response(result: Arc<RawValue>, id: Box<RawValue>) -> Self {
|
||||||
JsonRpcForwardedResponse {
|
JsonRpcForwardedResponse {
|
||||||
jsonrpc: "2.0",
|
jsonrpc: "2.0",
|
||||||
id,
|
id,
|
||||||
@ -292,6 +293,9 @@ impl JsonRpcForwardedResponse {
|
|||||||
pub fn from_value(result: serde_json::Value, id: Box<RawValue>) -> Self {
|
pub fn from_value(result: serde_json::Value, id: Box<RawValue>) -> Self {
|
||||||
let partial_response = to_raw_value(&result).expect("Value to RawValue should always work");
|
let partial_response = to_raw_value(&result).expect("Value to RawValue should always work");
|
||||||
|
|
||||||
|
// TODO: an Arc is a waste here. change JsonRpcForwardedResponse to take an enum?
|
||||||
|
let partial_response = partial_response.into();
|
||||||
|
|
||||||
JsonRpcForwardedResponse {
|
JsonRpcForwardedResponse {
|
||||||
jsonrpc: "2.0",
|
jsonrpc: "2.0",
|
||||||
id,
|
id,
|
||||||
@ -339,7 +343,7 @@ impl JsonRpcForwardedResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn try_from_response_result(
|
pub fn try_from_response_result(
|
||||||
result: Result<Box<RawValue>, ProviderError>,
|
result: Result<Arc<RawValue>, ProviderError>,
|
||||||
id: Box<RawValue>,
|
id: Box<RawValue>,
|
||||||
) -> Web3ProxyResult<Self> {
|
) -> Web3ProxyResult<Self> {
|
||||||
match result {
|
match result {
|
||||||
@ -348,7 +352,7 @@ impl JsonRpcForwardedResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_response_data(data: JsonRpcResponseEnum<Box<RawValue>>, id: Box<RawValue>) -> Self {
|
pub fn from_response_data(data: JsonRpcResponseEnum<Arc<RawValue>>, id: Box<RawValue>) -> Self {
|
||||||
match data {
|
match data {
|
||||||
JsonRpcResponseEnum::Result { value, .. } => Self::from_raw_response(value, id),
|
JsonRpcResponseEnum::Result { value, .. } => Self::from_raw_response(value, id),
|
||||||
JsonRpcResponseEnum::RpcError {
|
JsonRpcResponseEnum::RpcError {
|
||||||
|
@ -8,6 +8,7 @@ use std::{
|
|||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
hash::{BuildHasher, Hash, Hasher},
|
hash::{BuildHasher, Hash, Hasher},
|
||||||
num::NonZeroU32,
|
num::NonZeroU32,
|
||||||
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, From)]
|
#[derive(Clone, Debug, Eq, From)]
|
||||||
@ -19,6 +20,9 @@ pub struct JsonRpcQueryCacheKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl JsonRpcQueryCacheKey {
|
impl JsonRpcQueryCacheKey {
|
||||||
|
pub fn hash(&self) -> u64 {
|
||||||
|
self.hash
|
||||||
|
}
|
||||||
pub fn from_block_num(&self) -> Option<U64> {
|
pub fn from_block_num(&self) -> Option<U64> {
|
||||||
self.from_block_num
|
self.from_block_num
|
||||||
}
|
}
|
||||||
@ -79,7 +83,7 @@ impl JsonRpcQueryCacheKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub type JsonRpcResponseCache =
|
pub type JsonRpcResponseCache =
|
||||||
CacheWithTTL<JsonRpcQueryCacheKey, JsonRpcResponseEnum<Box<RawValue>>, JsonRpcResponseWeigher>;
|
CacheWithTTL<u64, JsonRpcResponseEnum<Arc<RawValue>>, JsonRpcResponseWeigher>;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct JsonRpcResponseWeigher;
|
pub struct JsonRpcResponseWeigher;
|
||||||
@ -107,7 +111,7 @@ impl<R> JsonRpcResponseEnum<R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<serde_json::Value> for JsonRpcResponseEnum<Box<RawValue>> {
|
impl From<serde_json::Value> for JsonRpcResponseEnum<Arc<RawValue>> {
|
||||||
fn from(value: serde_json::Value) -> Self {
|
fn from(value: serde_json::Value) -> Self {
|
||||||
let value = RawValue::from_string(value.to_string()).unwrap();
|
let value = RawValue::from_string(value.to_string()).unwrap();
|
||||||
|
|
||||||
@ -115,12 +119,24 @@ impl From<serde_json::Value> for JsonRpcResponseEnum<Box<RawValue>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Box<RawValue>> for JsonRpcResponseEnum<Box<RawValue>> {
|
impl From<Arc<RawValue>> for JsonRpcResponseEnum<Arc<RawValue>> {
|
||||||
|
fn from(value: Arc<RawValue>) -> Self {
|
||||||
|
let num_bytes = value.get().len();
|
||||||
|
|
||||||
|
let num_bytes = NonZeroU32::try_from(num_bytes as u32).unwrap();
|
||||||
|
|
||||||
|
Self::Result { value, num_bytes }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Box<RawValue>> for JsonRpcResponseEnum<Arc<RawValue>> {
|
||||||
fn from(value: Box<RawValue>) -> Self {
|
fn from(value: Box<RawValue>) -> Self {
|
||||||
let num_bytes = value.get().len();
|
let num_bytes = value.get().len();
|
||||||
|
|
||||||
let num_bytes = NonZeroU32::try_from(num_bytes as u32).unwrap();
|
let num_bytes = NonZeroU32::try_from(num_bytes as u32).unwrap();
|
||||||
|
|
||||||
|
let value = value.into();
|
||||||
|
|
||||||
Self::Result { value, num_bytes }
|
Self::Result { value, num_bytes }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -140,7 +156,21 @@ impl<R> TryFrom<Web3ProxyError> for JsonRpcResponseEnum<R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<Result<Box<RawValue>, Web3ProxyError>> for JsonRpcResponseEnum<Box<RawValue>> {
|
impl TryFrom<Result<Arc<RawValue>, Web3ProxyError>> for JsonRpcResponseEnum<Arc<RawValue>> {
|
||||||
|
type Error = Web3ProxyError;
|
||||||
|
|
||||||
|
fn try_from(value: Result<Arc<RawValue>, Web3ProxyError>) -> Result<Self, Self::Error> {
|
||||||
|
match value {
|
||||||
|
Ok(x) => Ok(x.into()),
|
||||||
|
Err(err) => {
|
||||||
|
let x: Self = err.try_into()?;
|
||||||
|
|
||||||
|
Ok(x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl TryFrom<Result<Box<RawValue>, Web3ProxyError>> for JsonRpcResponseEnum<Arc<RawValue>> {
|
||||||
type Error = Web3ProxyError;
|
type Error = Web3ProxyError;
|
||||||
|
|
||||||
fn try_from(value: Result<Box<RawValue>, Web3ProxyError>) -> Result<Self, Self::Error> {
|
fn try_from(value: Result<Box<RawValue>, Web3ProxyError>) -> Result<Self, Self::Error> {
|
||||||
@ -205,8 +235,9 @@ impl TryFrom<ProviderError> for JsonRpcErrorData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<K, Q> Weighter<K, Q, JsonRpcResponseEnum<Box<RawValue>>> for JsonRpcResponseWeigher {
|
// TODO: instead of Arc<RawValue>, be generic
|
||||||
fn weight(&self, _key: &K, _qey: &Q, value: &JsonRpcResponseEnum<Box<RawValue>>) -> NonZeroU32 {
|
impl<K, Q> Weighter<K, Q, JsonRpcResponseEnum<Arc<RawValue>>> for JsonRpcResponseWeigher {
|
||||||
|
fn weight(&self, _key: &K, _qey: &Q, value: &JsonRpcResponseEnum<Arc<RawValue>>) -> NonZeroU32 {
|
||||||
value.num_bytes()
|
value.num_bytes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -216,7 +247,7 @@ mod tests {
|
|||||||
use super::{JsonRpcResponseEnum, JsonRpcResponseWeigher};
|
use super::{JsonRpcResponseEnum, JsonRpcResponseWeigher};
|
||||||
use quick_cache_ttl::CacheWithTTL;
|
use quick_cache_ttl::CacheWithTTL;
|
||||||
use serde_json::value::RawValue;
|
use serde_json::value::RawValue;
|
||||||
use std::{num::NonZeroU32, time::Duration};
|
use std::{num::NonZeroU32, 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() {
|
||||||
@ -225,7 +256,7 @@ mod tests {
|
|||||||
|
|
||||||
let test_cache: CacheWithTTL<
|
let test_cache: CacheWithTTL<
|
||||||
u32,
|
u32,
|
||||||
JsonRpcResponseEnum<Box<RawValue>>,
|
JsonRpcResponseEnum<Arc<RawValue>>,
|
||||||
JsonRpcResponseWeigher,
|
JsonRpcResponseWeigher,
|
||||||
> = CacheWithTTL::new_with_weights(
|
> = CacheWithTTL::new_with_weights(
|
||||||
"test",
|
"test",
|
||||||
@ -238,17 +269,17 @@ mod tests {
|
|||||||
.await;
|
.await;
|
||||||
|
|
||||||
let small_data = JsonRpcResponseEnum::Result {
|
let small_data = JsonRpcResponseEnum::Result {
|
||||||
value: Default::default(),
|
value: Box::<RawValue>::default().into(),
|
||||||
num_bytes: NonZeroU32::try_from(max_item_weight / 2).unwrap(),
|
num_bytes: NonZeroU32::try_from(max_item_weight / 2).unwrap(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let max_sized_data = JsonRpcResponseEnum::Result {
|
let max_sized_data = JsonRpcResponseEnum::Result {
|
||||||
value: Default::default(),
|
value: Box::<RawValue>::default().into(),
|
||||||
num_bytes: NonZeroU32::try_from(max_item_weight).unwrap(),
|
num_bytes: NonZeroU32::try_from(max_item_weight).unwrap(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let oversized_data = JsonRpcResponseEnum::Result {
|
let oversized_data = JsonRpcResponseEnum::Result {
|
||||||
value: Default::default(),
|
value: Box::<RawValue>::default().into(),
|
||||||
num_bytes: NonZeroU32::try_from(max_item_weight * 2).unwrap(),
|
num_bytes: NonZeroU32::try_from(max_item_weight * 2).unwrap(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user