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
use crate::Pea2Pea;
use fxhash::FxHashSet;
use std::io;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Topology {
Line,
Ring,
Mesh,
Star,
}
pub async fn connect_nodes<T: Pea2Pea>(nodes: &[T], topology: Topology) -> io::Result<()> {
let count = nodes.len();
if count < 2 {
return Err(io::ErrorKind::InvalidInput.into());
}
match topology {
Topology::Line | Topology::Ring => {
for i in 0..(count - 1) {
let addr = nodes[i + 1].node().listening_addr()?;
nodes[i].node().connect(addr).await?;
}
if topology == Topology::Ring {
let addr = nodes[0].node().listening_addr()?;
nodes[count - 1].node().connect(addr).await?;
}
}
Topology::Mesh => {
let mut connected_pairs =
FxHashSet::with_capacity_and_hasher((count - 1) * 2, Default::default());
for i in 0..count {
for (j, peer) in nodes.iter().enumerate() {
if i != j && connected_pairs.insert((i, j)) && connected_pairs.insert((j, i)) {
let addr = peer.node().listening_addr()?;
nodes[i].node().connect(addr).await?;
}
}
}
}
Topology::Star => {
let hub_addr = nodes[0].node().listening_addr()?;
for node in nodes.iter().skip(1) {
node.node().connect(hub_addr).await?;
}
}
}
Ok(())
}