Skip to content

Commit 98333cf

Browse files
committed
split function to flatten recursion
1 parent 8da65b5 commit 98333cf

3 files changed

Lines changed: 38 additions & 35 deletions

File tree

duva/src/lib.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,17 +112,19 @@ impl StartUpFacade {
112112
// #1 Check if it has persisted cluster node info locally, if it does and finds some other nodes, try connect
113113
// #2 Otherwise, check if this node is a follower and connect to the leader
114114
async fn discover_peers(&self) -> anyhow::Result<()> {
115-
let connection_manager = self.registry.cluster_connection_manager();
116-
let peer_identifier = self
115+
let connect_to = self
117116
.registry
118117
.cluster_communication_manager()
119118
.replication_info()
120119
.await?
121120
.leader_bind_addr()
122121
.context("No leader bind address found")?;
123-
let (tx, rx) = tokio::sync::oneshot::channel();
124-
connection_manager.discover_cluster(self.config_manager.port, peer_identifier, tx).await?;
125-
let _ = rx.await;
122+
123+
self.registry
124+
.cluster_connection_manager()
125+
.discover_cluster(self.config_manager.port, connect_to)
126+
.await?;
127+
126128
Ok(())
127129
}
128130

duva/src/presentation/clients/controllers/handler.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,10 @@ impl ClientController<Handler> {
9696
ClientAction::ReplicaOf(peer_identifier) => {
9797
self.cluster_communication_manager.replicaof(peer_identifier.clone()).await;
9898

99-
let (tx, rx) = tokio::sync::oneshot::channel();
10099
ClusterConnectionManager(self.cluster_communication_manager.clone())
101-
.discover_cluster(self.config_manager.port, peer_identifier, tx)
100+
.discover_cluster(self.config_manager.port, peer_identifier)
102101
.await?;
103-
let _ = rx.await;
102+
104103
QueryIO::SimpleString("OK".into())
105104
},
106105
};

duva/src/presentation/clusters/connection_manager.rs

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
use std::collections::VecDeque;
2+
13
use super::communication_manager::ClusterCommunicationManager;
24
use super::outbound::stream::OutboundStream;
35

46
use crate::domains::cluster_actors::commands::ClusterCommand;
57
use crate::domains::peers::identifier::PeerIdentifier;
68
use crate::{InboundStream, make_smart_pointer};
7-
use tokio::sync::mpsc::Sender;
89

910
pub(crate) struct ClusterConnectionManager(pub(crate) ClusterCommunicationManager);
1011

@@ -20,7 +21,7 @@ impl ClusterConnectionManager {
2021
peer_stream.may_try_sync(ccm, &connected_peer_info).await?;
2122

2223
let (tx, rx) = tokio::sync::oneshot::channel();
23-
self.send(peer_stream.into_add_peer(self.clone(), connected_peer_info, tx)?).await?;
24+
self.send(peer_stream.into_add_peer(self.0.0.clone(), connected_peer_info, tx)?).await?;
2425

2526
Ok(())
2627
}
@@ -29,45 +30,46 @@ impl ClusterConnectionManager {
2930
self,
3031
self_port: u16,
3132
connect_to: PeerIdentifier,
32-
sender: tokio::sync::oneshot::Sender<()>,
3333
) -> anyhow::Result<()> {
34-
// Base case
34+
let mut queue = VecDeque::from(vec![connect_to.clone()]);
35+
let mut callbacks = Vec::new();
36+
while let Some(connect_to) = queue.pop_front() {
37+
let (tx, rx) = tokio::sync::oneshot::channel();
38+
queue.extend(
39+
ClusterConnectionManager(self.clone())
40+
.connect_to_server(self_port, connect_to, tx)
41+
.await?,
42+
);
43+
callbacks.push(rx);
44+
}
45+
for callback in callbacks {
46+
let _ = callback.await;
47+
}
48+
Ok(())
49+
}
50+
51+
async fn connect_to_server(
52+
self,
53+
self_port: u16,
54+
connect_to: PeerIdentifier,
55+
sender: tokio::sync::oneshot::Sender<()>,
56+
) -> anyhow::Result<Vec<PeerIdentifier>> {
3557
let existing_peers = self.get_peers().await?;
3658
if existing_peers.contains(&connect_to) {
37-
return Ok(());
59+
return Ok(vec![]);
3860
}
3961

40-
// Recursive case
4162
let replication_info = self.replication_info().await?;
4263
let (add_peer_cmd, peer_list) = OutboundStream::new(connect_to, replication_info)
4364
.await?
4465
.establish_connection(self_port)
4566
.await?
4667
.set_replication_info(&self)
4768
.await?
48-
.create_peer_cmd(self.clone(), sender)?;
69+
.create_peer_cmd(self.0.0.clone(), sender)?;
4970
self.send(add_peer_cmd).await?;
5071

51-
// Discover additional peers concurrently
52-
// TODO Require investigation. Why does 'list_peer_binding_addrs' have to be called at here?
53-
let mut callbacks = Vec::new();
54-
for peer in peer_list {
55-
println!("Discovering peer: {}", peer);
56-
let (tx, rx) = tokio::sync::oneshot::channel();
57-
Box::pin(
58-
ClusterConnectionManager(self.0.clone()).discover_cluster(self_port, peer, tx),
59-
)
60-
.await?;
61-
callbacks.push(rx);
62-
}
63-
for callback in callbacks {
64-
let _ = callback.await;
65-
}
66-
Ok(())
67-
}
68-
69-
pub fn clone(&self) -> Sender<ClusterCommand> {
70-
self.0.0.clone()
72+
Ok(peer_list)
7173
}
7274

7375
pub async fn send(&self, cmd: ClusterCommand) -> anyhow::Result<()> {

0 commit comments

Comments
 (0)