mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 15:41:02 +00:00
Actually clone client data by reference when cloning the client (#1941)
* actually clone client data by reference when clonning the client * spelling * clippy
This commit is contained in:
committed by
Bastian Köcher
parent
e0c0861bc7
commit
f4ca16b98d
@@ -26,7 +26,7 @@ use crate::{
|
||||
Result, SignParam, TransactionTracker, UnsignedTransaction,
|
||||
};
|
||||
|
||||
use async_std::sync::{Arc, Mutex};
|
||||
use async_std::sync::{Arc, Mutex, RwLock};
|
||||
use async_trait::async_trait;
|
||||
use bp_runtime::{HeaderIdProvider, StorageDoubleMapKeyProvider, StorageMapKeyProvider};
|
||||
use codec::{Decode, Encode};
|
||||
@@ -111,23 +111,31 @@ pub enum ChainRuntimeVersion {
|
||||
|
||||
/// Substrate client type.
|
||||
///
|
||||
/// Cloning `Client` is a cheap operation.
|
||||
/// Cloning `Client` is a cheap operation that only clones internal references. Different
|
||||
/// clones of the same client are guaranteed to use the same references.
|
||||
pub struct Client<C: Chain> {
|
||||
/// Tokio runtime handle.
|
||||
tokio: Arc<tokio::runtime::Runtime>,
|
||||
// Lock order: `submit_signed_extrinsic_lock`, `data`
|
||||
/// Client connection params.
|
||||
params: Arc<ConnectionParams>,
|
||||
/// Substrate RPC client.
|
||||
client: Arc<RpcClient>,
|
||||
/// Genesis block hash.
|
||||
genesis_hash: HashOf<C>,
|
||||
/// Saved chain runtime version.
|
||||
chain_runtime_version: ChainRuntimeVersion,
|
||||
/// If several tasks are submitting their transactions simultaneously using
|
||||
/// `submit_signed_extrinsic` method, they may get the same transaction nonce. So one of
|
||||
/// transactions will be rejected from the pool. This lock is here to prevent situations like
|
||||
/// that.
|
||||
submit_signed_extrinsic_lock: Arc<Mutex<()>>,
|
||||
/// Saved chain runtime version
|
||||
chain_runtime_version: ChainRuntimeVersion,
|
||||
/// Genesis block hash.
|
||||
genesis_hash: HashOf<C>,
|
||||
/// Shared dynamic data.
|
||||
data: Arc<RwLock<ClientData>>,
|
||||
}
|
||||
|
||||
/// Client data, shared by all `Client` clones.
|
||||
struct ClientData {
|
||||
/// Tokio runtime handle.
|
||||
tokio: Arc<tokio::runtime::Runtime>,
|
||||
/// Substrate RPC client.
|
||||
client: Arc<RpcClient>,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
@@ -135,9 +143,10 @@ impl<C: Chain> relay_utils::relay_loop::Client for Client<C> {
|
||||
type Error = Error;
|
||||
|
||||
async fn reconnect(&mut self) -> Result<()> {
|
||||
let mut data = self.data.write().await;
|
||||
let (tokio, client) = Self::build_client(&self.params).await?;
|
||||
self.tokio = tokio;
|
||||
self.client = client;
|
||||
data.tokio = tokio;
|
||||
data.client = client;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -145,12 +154,11 @@ impl<C: Chain> relay_utils::relay_loop::Client for Client<C> {
|
||||
impl<C: Chain> Clone for Client<C> {
|
||||
fn clone(&self) -> Self {
|
||||
Client {
|
||||
tokio: self.tokio.clone(),
|
||||
params: self.params.clone(),
|
||||
client: self.client.clone(),
|
||||
genesis_hash: self.genesis_hash,
|
||||
submit_signed_extrinsic_lock: self.submit_signed_extrinsic_lock.clone(),
|
||||
chain_runtime_version: self.chain_runtime_version.clone(),
|
||||
submit_signed_extrinsic_lock: self.submit_signed_extrinsic_lock.clone(),
|
||||
genesis_hash: self.genesis_hash,
|
||||
data: self.data.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -199,12 +207,11 @@ impl<C: Chain> Client<C> {
|
||||
|
||||
let chain_runtime_version = params.chain_runtime_version.clone();
|
||||
Ok(Self {
|
||||
tokio,
|
||||
params,
|
||||
client,
|
||||
genesis_hash,
|
||||
submit_signed_extrinsic_lock: Arc::new(Mutex::new(())),
|
||||
chain_runtime_version,
|
||||
submit_signed_extrinsic_lock: Arc::new(Mutex::new(())),
|
||||
genesis_hash,
|
||||
data: Arc::new(RwLock::new(ClientData { tokio, client })),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -572,7 +579,7 @@ impl<C: Chain> Client<C> {
|
||||
Ok((tracker, subscription))
|
||||
})
|
||||
.await?;
|
||||
self.tokio.spawn(Subscription::background_worker(
|
||||
self.data.read().await.tokio.spawn(Subscription::background_worker(
|
||||
C::NAME.into(),
|
||||
"extrinsic".into(),
|
||||
subscription,
|
||||
@@ -719,7 +726,7 @@ impl<C: Chain> Client<C> {
|
||||
})
|
||||
.await?;
|
||||
let (sender, receiver) = futures::channel::mpsc::channel(MAX_SUBSCRIPTION_CAPACITY);
|
||||
self.tokio.spawn(Subscription::background_worker(
|
||||
self.data.read().await.tokio.spawn(Subscription::background_worker(
|
||||
C::NAME.into(),
|
||||
"justification".into(),
|
||||
subscription,
|
||||
@@ -735,8 +742,9 @@ impl<C: Chain> Client<C> {
|
||||
F: Future<Output = Result<T>> + Send,
|
||||
T: Send + 'static,
|
||||
{
|
||||
let client = self.client.clone();
|
||||
self.tokio.spawn(async move { make_jsonrpsee_future(client).await }).await?
|
||||
let data = self.data.read().await;
|
||||
let client = data.client.clone();
|
||||
data.tokio.spawn(async move { make_jsonrpsee_future(client).await }).await?
|
||||
}
|
||||
|
||||
/// Returns `true` if version guard can be started.
|
||||
|
||||
Reference in New Issue
Block a user