substrate_api_client/api/rpc_api/
runtime_update.rsuse crate::{api::Error, rpc::Subscribe, rpc_api::EventSubscriptionFor, Result};
use alloc::sync::Arc;
use codec::{Decode, Encode};
use core::sync::atomic::{AtomicBool, Ordering};
use serde::de::DeserializeOwned;
pub struct RuntimeUpdateDetector<Hash, Client>
where
Hash: DeserializeOwned + Copy + Decode,
Client: Subscribe,
{
subscription: EventSubscriptionFor<Client, Hash>,
external_cancellation: Option<Arc<AtomicBool>>,
}
impl<Hash, Client> RuntimeUpdateDetector<Hash, Client>
where
Hash: DeserializeOwned + Copy + Encode + Decode,
Client: Subscribe,
{
pub fn new(subscription: EventSubscriptionFor<Client, Hash>) -> Self {
Self { subscription, external_cancellation: None }
}
pub fn new_with_cancellation(
subscription: EventSubscriptionFor<Client, Hash>,
cancellation: Arc<AtomicBool>,
) -> Self {
Self { subscription, external_cancellation: Some(cancellation) }
}
#[maybe_async::maybe_async(?Send)]
pub async fn detect_runtime_update(&mut self) -> Result<bool> {
'outer: loop {
if let Some(canceled) = &self.external_cancellation {
if canceled.load(Ordering::SeqCst) {
return Ok(false)
}
}
let event_records = self
.subscription
.next_events_from_metadata()
.await
.ok_or(Error::Other("Error receiving events".into()))??;
let event_iter = event_records.iter();
for event in event_iter {
if event?.is_code_update() {
break 'outer
}
}
}
Ok(true)
}
}