54 lines
1.7 KiB
Rust

use std::time::Duration;
use testing_framework_core::scenario::{BlockFeed, BlockFeedTask, NodeClients, spawn_block_feed};
use tokio::time::sleep;
use tracing::{debug, info, warn};
use crate::errors::ComposeRunnerError;
const BLOCK_FEED_MAX_ATTEMPTS: usize = 5;
const BLOCK_FEED_RETRY_DELAY: Duration = Duration::from_secs(1);
async fn spawn_block_feed_with(
node_clients: &NodeClients,
) -> Result<(BlockFeed, BlockFeedTask), ComposeRunnerError> {
debug!(
validators = node_clients.validator_clients().len(),
executors = node_clients.executor_clients().len(),
"selecting validator client for block feed"
);
let block_source_client = node_clients
.random_validator()
.cloned()
.ok_or(ComposeRunnerError::BlockFeedMissing)?;
spawn_block_feed(block_source_client)
.await
.map_err(|source| ComposeRunnerError::BlockFeed { source })
}
pub async fn spawn_block_feed_with_retry(
node_clients: &NodeClients,
) -> Result<(BlockFeed, BlockFeedTask), ComposeRunnerError> {
let mut last_err = None;
for attempt in 1..=BLOCK_FEED_MAX_ATTEMPTS {
info!(attempt, "starting block feed");
match spawn_block_feed_with(node_clients).await {
Ok(result) => {
info!(attempt, "block feed established");
return Ok(result);
}
Err(err) => {
last_err = Some(err);
if attempt < BLOCK_FEED_MAX_ATTEMPTS {
warn!(attempt, "block feed initialization failed; retrying");
sleep(BLOCK_FEED_RETRY_DELAY).await;
}
}
}
}
Err(last_err.expect("block feed retry should capture an error"))
}