use std::{sync::atomic::Ordering, time::Duration};
use tokio::time::sleep;
use crate::{
client::secret::SecretManage,
wallet::{account::operations::syncing::SyncOptions, Wallet},
};
pub(crate) const DEFAULT_BACKGROUNDSYNCING_INTERVAL: Duration = Duration::from_secs(7);
impl<S: 'static + SecretManage> Wallet<S>
where
crate::wallet::Error: From<S::Error>,
{
pub async fn start_background_syncing(
&self,
options: Option<SyncOptions>,
interval: Option<Duration>,
) -> crate::wallet::Result<()> {
log::debug!("[start_background_syncing]");
if self.background_syncing_status.load(Ordering::Relaxed) == 1 {
self.background_syncing_status.store(2, Ordering::Relaxed);
};
while self.background_syncing_status.load(Ordering::Relaxed) == 2 {
log::debug!("[background_syncing]: waiting for the old process to stop");
sleep(Duration::from_secs(1)).await;
}
self.background_syncing_status.store(1, Ordering::Relaxed);
let wallet = self.clone();
let _background_syncing = std::thread::spawn(move || {
#[cfg(not(target_family = "wasm"))]
let runtime = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap();
#[cfg(target_family = "wasm")]
let runtime = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap();
runtime.block_on(async {
'outer: loop {
log::debug!("[background_syncing]: syncing accounts");
for account in wallet.accounts.read().await.iter() {
if wallet.background_syncing_status.load(Ordering::Relaxed) == 2 {
log::debug!("[background_syncing]: stopping");
break 'outer;
}
match account.sync(options.clone()).await {
Ok(_) => {}
Err(err) => log::debug!("[background_syncing] error: {}", err),
};
}
let seconds = interval.unwrap_or(DEFAULT_BACKGROUNDSYNCING_INTERVAL).as_secs();
for _ in 0..seconds {
if wallet.background_syncing_status.load(Ordering::Relaxed) == 2 {
log::debug!("[background_syncing]: stopping");
break 'outer;
}
sleep(Duration::from_secs(1)).await;
}
}
wallet.background_syncing_status.store(0, Ordering::Relaxed);
log::debug!("[background_syncing]: stopped");
});
});
Ok(())
}
pub async fn stop_background_syncing(&self) -> crate::wallet::Result<()> {
log::debug!("[stop_background_syncing]");
if self.background_syncing_status.load(Ordering::Relaxed) == 0 {
return Ok(());
}
self.background_syncing_status.store(2, Ordering::Relaxed);
while self.background_syncing_status.load(Ordering::Relaxed) != 0 {
#[cfg(target_family = "wasm")]
gloo_timers::future::TimeoutFuture::new(10).await;
#[cfg(not(target_family = "wasm"))]
tokio::time::sleep(std::time::Duration::from_millis(10)).await;
}
Ok(())
}
}