1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#![forbid(unsafe_code)]
use std::{fmt, time::Duration};
use crate::{
cluster::Cluster,
experiments::{Context, Experiment, ExperimentParam},
instance,
instance::Instance,
};
use async_trait::async_trait;
use diem_logger::info;
use futures::future::try_join_all;
use std::{
collections::HashSet,
fmt::{Error, Formatter},
};
use structopt::StructOpt;
use tokio::time;
#[derive(StructOpt, Debug)]
pub struct RebootClusterParams {}
pub struct RebootCluster {
instances: Vec<Instance>,
}
impl ExperimentParam for RebootClusterParams {
type E = RebootCluster;
fn build(self, cluster: &Cluster) -> Self::E {
Self::E {
instances: <&[instance::Instance]>::clone(&cluster.validator_instances()).to_vec(),
}
}
}
#[async_trait]
impl Experiment for RebootCluster {
fn affected_validators(&self) -> HashSet<String> {
instance::instancelist_to_set(&self.instances)
}
async fn run(&mut self, _context: &mut Context<'_>) -> anyhow::Result<()> {
let futures: Vec<_> = self.instances.iter().map(Instance::stop).collect();
try_join_all(futures).await?;
for inst in &self.instances {
info!("Starting node {}", inst.peer_name());
inst.start().await?;
time::sleep(Duration::from_secs(10)).await;
}
Ok(())
}
fn deadline(&self) -> Duration {
Duration::from_secs(20 * 60)
}
}
impl fmt::Display for RebootCluster {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
write!(f, "Reboot cluster")
}
}