layer_climb_core/
cache.rs1use anyhow::Result;
2use layer_climb_config::ChainConfig;
3use std::{
4 collections::HashMap,
5 sync::{Arc, Mutex},
6};
7
8use crate::network::rpc::{RpcClient, RpcTransport};
9
10#[derive(Clone)]
17pub struct ClimbCache {
18 #[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
19 grpc: Arc<Mutex<HashMap<String, tonic_web_wasm_client::Client>>>,
20 #[cfg(all(target_arch = "wasm32", not(target_os = "unknown")))]
21 #[allow(dead_code)]
22 grpc: Arc<Mutex<HashMap<String, crate::network::grpc_wasi::Client>>>,
23 #[cfg(not(target_arch = "wasm32"))]
24 grpc: Arc<Mutex<HashMap<String, tonic::transport::Channel>>>,
25 rpc: Arc<Mutex<HashMap<String, RpcClient>>>,
26 rpc_transport: Arc<dyn RpcTransport>,
27}
28
29impl ClimbCache {
30 pub fn new(rpc_transport: Arc<dyn RpcTransport>) -> Self {
31 Self {
32 grpc: Arc::new(Mutex::new(HashMap::new())),
33 rpc: Arc::new(Mutex::new(HashMap::new())),
34 rpc_transport,
35 }
36 }
37}
38
39impl ClimbCache {
40 pub fn get_rpc_client(&self, config: &ChainConfig) -> Option<RpcClient> {
41 match config.rpc_endpoint.as_ref() {
42 None => None,
43 Some(endpoint) => {
44 let rpc = { self.rpc.lock().unwrap().get(endpoint).cloned() };
45
46 Some(match rpc {
47 Some(rpc) => rpc,
48 None => {
49 let rpc = RpcClient::new(endpoint.to_string(), self.rpc_transport.clone());
50 self.rpc
51 .lock()
52 .unwrap()
53 .insert(endpoint.to_string(), rpc.clone());
54 rpc
55 }
56 })
57 }
58 }
59 }
60}
61cfg_if::cfg_if! {
62 if #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] {
63 impl ClimbCache {
64 pub async fn get_web_grpc(&self, chain_config: &ChainConfig) -> Result<Option<tonic_web_wasm_client::Client>> {
65 let endpoint = match chain_config.grpc_web_endpoint.as_ref() {
66 Some(endpoint) => endpoint.to_string(),
67 None => match chain_config.grpc_endpoint.as_ref() {
68 Some(endpoint) => endpoint.to_string(),
69 None => return Ok(None),
70 }
71 };
72
73
74 let grpc = {
75 self.grpc.lock().unwrap().get(&endpoint).cloned()
76 };
77
78 Ok(Some(match grpc {
79 Some(grpc) => grpc,
80 None => {
81 let grpc = crate::network::grpc_web::make_grpc_client(endpoint.clone()).await?;
82 self.grpc.lock().unwrap().insert(endpoint, grpc.clone());
83 grpc
84 }
85 }))
86 }
87 }
88 } else if #[cfg(target_arch = "wasm32")] {
89 impl ClimbCache {
90 pub async fn get_wasi_grpc(&self, _chain_config: &ChainConfig) -> Result<Option<crate::network::grpc_wasi::Client>> {
91 unimplemented!();
92 }
93 }
94 } else {
95 impl ClimbCache {
96 pub async fn get_grpc(&self, chain_config: &ChainConfig) -> Result<Option<tonic::transport::Channel>> {
97 match chain_config.grpc_endpoint.as_ref() {
98 None => Ok(None),
99 Some(endpoint) => {
100 let grpc = {
101 self.grpc.lock().unwrap().get(endpoint).cloned()
102 };
103
104 Ok(Some(match grpc {
105 Some(grpc) => grpc,
106 None => {
107 tracing::debug!("Creating new grpc channel for {}", endpoint);
108 let grpc = crate::network::grpc_native::make_grpc_channel(endpoint).await?;
109 self.grpc.lock().unwrap().insert(endpoint.to_string(), grpc.clone());
110 grpc
111 }
112 }))
113 }
114 }
115 }
116 }
117 }
118}