mirror of
https://github.com/pezkuwichain/revive-differential-tests.git
synced 2026-04-29 05:27:59 +00:00
97 lines
2.9 KiB
Rust
97 lines
2.9 KiB
Rust
//! This crate implements concurrent handling of testing node.
|
|
|
|
use std::{
|
|
sync::atomic::{AtomicUsize, Ordering},
|
|
thread,
|
|
};
|
|
|
|
use alloy::genesis::Genesis;
|
|
use anyhow::Context as _;
|
|
use revive_dt_config::{
|
|
ConcurrencyConfiguration, EthRpcConfiguration, GenesisConfiguration, GethConfiguration,
|
|
KitchensinkConfiguration, ReviveDevNodeConfiguration, WalletConfiguration,
|
|
WorkingDirectoryConfiguration,
|
|
};
|
|
|
|
use crate::Node;
|
|
|
|
/// The node pool starts one or more [Node] which then can be accessed
|
|
/// in a round robbin fashion.
|
|
pub struct NodePool<T> {
|
|
next: AtomicUsize,
|
|
nodes: Vec<T>,
|
|
}
|
|
|
|
impl<T> NodePool<T>
|
|
where
|
|
T: Node + Send + 'static,
|
|
{
|
|
/// Create a new Pool. This will start as many nodes as there are workers in `config`.
|
|
pub fn new(
|
|
context: impl AsRef<WorkingDirectoryConfiguration>
|
|
+ AsRef<ConcurrencyConfiguration>
|
|
+ AsRef<GenesisConfiguration>
|
|
+ AsRef<WalletConfiguration>
|
|
+ AsRef<GethConfiguration>
|
|
+ AsRef<KitchensinkConfiguration>
|
|
+ AsRef<ReviveDevNodeConfiguration>
|
|
+ AsRef<EthRpcConfiguration>
|
|
+ Send
|
|
+ Sync
|
|
+ Clone
|
|
+ 'static,
|
|
) -> anyhow::Result<Self> {
|
|
let concurrency_configuration = AsRef::<ConcurrencyConfiguration>::as_ref(&context);
|
|
let genesis_configuration = AsRef::<GenesisConfiguration>::as_ref(&context);
|
|
|
|
let nodes = concurrency_configuration.number_of_nodes;
|
|
let genesis = genesis_configuration.genesis()?;
|
|
|
|
let mut handles = Vec::with_capacity(nodes);
|
|
for _ in 0..nodes {
|
|
let context = context.clone();
|
|
let genesis = genesis.clone();
|
|
handles.push(thread::spawn(move || spawn_node::<T>(context, genesis)));
|
|
}
|
|
|
|
let mut nodes = Vec::with_capacity(nodes);
|
|
for handle in handles {
|
|
nodes.push(
|
|
handle
|
|
.join()
|
|
.map_err(|error| anyhow::anyhow!("failed to spawn node: {:?}", error))
|
|
.context("Failed to join node spawn thread")?
|
|
.map_err(|error| anyhow::anyhow!("node failed to spawn: {error}"))
|
|
.context("Node failed to spawn")?,
|
|
);
|
|
}
|
|
|
|
Ok(Self {
|
|
nodes,
|
|
next: Default::default(),
|
|
})
|
|
}
|
|
|
|
/// Get a handle to the next node.
|
|
pub fn round_robbin(&self) -> &T {
|
|
let current = self.next.fetch_add(1, Ordering::SeqCst) % self.nodes.len();
|
|
self.nodes.get(current).unwrap()
|
|
}
|
|
}
|
|
|
|
fn spawn_node<T: Node + Send>(
|
|
_: impl AsRef<WorkingDirectoryConfiguration>
|
|
+ AsRef<ConcurrencyConfiguration>
|
|
+ AsRef<GenesisConfiguration>
|
|
+ AsRef<WalletConfiguration>
|
|
+ AsRef<GethConfiguration>
|
|
+ AsRef<KitchensinkConfiguration>
|
|
+ AsRef<ReviveDevNodeConfiguration>
|
|
+ AsRef<EthRpcConfiguration>
|
|
+ Clone
|
|
+ 'static,
|
|
_: Genesis,
|
|
) -> anyhow::Result<T> {
|
|
todo!("Remove");
|
|
}
|