|
|
@@ -31,8 +31,8 @@ impl InboundInfo {
|
|
|
pub struct InboundSession {
|
|
|
p2p: Weak<P2p>,
|
|
|
acceptor: AcceptorPtr,
|
|
|
- accept_task: StoppableTaskPtr,
|
|
|
- connect_infos: Mutex<FxHashMap<Url, InboundInfo>>,
|
|
|
+ accept_tasks: Mutex<Vec<StoppableTaskPtr>>,
|
|
|
+ connect_infos: Mutex<Vec<FxHashMap<Url, InboundInfo>>>,
|
|
|
}
|
|
|
|
|
|
impl InboundSession {
|
|
|
@@ -43,8 +43,8 @@ impl InboundSession {
|
|
|
let self_ = Arc::new(Self {
|
|
|
p2p,
|
|
|
acceptor,
|
|
|
- accept_task: StoppableTask::new(),
|
|
|
- connect_infos: Mutex::new(FxHashMap::default()),
|
|
|
+ accept_tasks: Mutex::new(Vec::new()),
|
|
|
+ connect_infos: Mutex::new(Vec::new()),
|
|
|
});
|
|
|
|
|
|
let parent = Arc::downgrade(&self_);
|
|
|
@@ -55,57 +55,73 @@ impl InboundSession {
|
|
|
}
|
|
|
|
|
|
/// Starts the inbound session. Begins by accepting connections and fails if
|
|
|
- /// the address is not configured. Then runs the channel subscription
|
|
|
+ /// the addresses are not configured. Then runs the channel subscription
|
|
|
/// loop.
|
|
|
pub async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
|
|
|
- match self.p2p().settings().inbound.as_ref() {
|
|
|
- Some(accept_addr) => {
|
|
|
- self.clone().start_accept_session(accept_addr.clone(), executor.clone()).await?;
|
|
|
- }
|
|
|
- None => {
|
|
|
- info!(target: "net", "Not configured for accepting incoming connections.");
|
|
|
- return Ok(())
|
|
|
- }
|
|
|
+ if self.p2p().settings().inbound.is_empty() {
|
|
|
+ info!(target: "net", "Not configured for accepting incoming connections.");
|
|
|
+ return Ok(())
|
|
|
}
|
|
|
|
|
|
- self.accept_task.clone().start(
|
|
|
- self.clone().channel_sub_loop(executor.clone()),
|
|
|
- // Ignore stop handler
|
|
|
- |_| async {},
|
|
|
- Error::NetworkServiceStopped,
|
|
|
- executor,
|
|
|
- );
|
|
|
+ // Activate mutex lock on connection slots.
|
|
|
+ let mut accept_tasks = self.accept_tasks.lock().await;
|
|
|
+
|
|
|
+ for (index, accept_addr) in self.p2p().settings().inbound.iter().enumerate() {
|
|
|
+ self.clone().start_accept_session(index, accept_addr.clone(), executor.clone()).await?;
|
|
|
+
|
|
|
+ let task = StoppableTask::new();
|
|
|
+
|
|
|
+ task.clone().start(
|
|
|
+ self.clone().channel_sub_loop(index, executor.clone()),
|
|
|
+ // Ignore stop handler
|
|
|
+ |_| async {},
|
|
|
+ Error::NetworkServiceStopped,
|
|
|
+ executor.clone(),
|
|
|
+ );
|
|
|
+
|
|
|
+ self.connect_infos.lock().await.push(FxHashMap::default());
|
|
|
+ accept_tasks.push(task);
|
|
|
+ }
|
|
|
|
|
|
Ok(())
|
|
|
}
|
|
|
/// Stops the inbound session.
|
|
|
pub async fn stop(&self) {
|
|
|
self.acceptor.stop().await;
|
|
|
- self.accept_task.stop().await;
|
|
|
+
|
|
|
+ let accept_tasks = &*self.accept_tasks.lock().await;
|
|
|
+ for accept_task in accept_tasks {
|
|
|
+ accept_task.stop().await;
|
|
|
+ }
|
|
|
}
|
|
|
/// Start accepting connections for inbound session.
|
|
|
async fn start_accept_session(
|
|
|
self: Arc<Self>,
|
|
|
+ index: usize,
|
|
|
accept_addr: Url,
|
|
|
executor: Arc<Executor<'_>>,
|
|
|
) -> Result<()> {
|
|
|
- info!(target: "net", "Starting inbound session on {}", accept_addr);
|
|
|
+ info!(target: "net", "#{} starting inbound session on {}", index, accept_addr);
|
|
|
let result = self.acceptor.clone().start(accept_addr, executor).await;
|
|
|
if let Err(err) = result.clone() {
|
|
|
- error!(target: "net", "Error starting listener: {}", err);
|
|
|
+ error!(target: "net", "#{} error starting listener: {}", index, err);
|
|
|
}
|
|
|
result
|
|
|
}
|
|
|
|
|
|
/// Wait for all new channels created by the acceptor and call
|
|
|
/// setup_channel() on them.
|
|
|
- async fn channel_sub_loop(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
|
|
|
+ async fn channel_sub_loop(
|
|
|
+ self: Arc<Self>,
|
|
|
+ index: usize,
|
|
|
+ executor: Arc<Executor<'_>>,
|
|
|
+ ) -> Result<()> {
|
|
|
let channel_sub = self.acceptor.clone().subscribe().await;
|
|
|
loop {
|
|
|
let channel = channel_sub.receive().await?;
|
|
|
// Spawn a detached task to process the channel
|
|
|
// This will just perform the channel setup then exit.
|
|
|
- executor.spawn(self.clone().setup_channel(channel, executor.clone())).detach();
|
|
|
+ executor.spawn(self.clone().setup_channel(index, channel, executor.clone())).detach();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -114,23 +130,22 @@ impl InboundSession {
|
|
|
/// channel.
|
|
|
async fn setup_channel(
|
|
|
self: Arc<Self>,
|
|
|
+ index: usize,
|
|
|
channel: ChannelPtr,
|
|
|
executor: Arc<Executor<'_>>,
|
|
|
) -> Result<()> {
|
|
|
- info!(target: "net", "Connected inbound [{}]", channel.address());
|
|
|
+ info!(target: "net", "#{} connected inbound [{}]", index, channel.address());
|
|
|
|
|
|
self.clone().register_channel(channel.clone(), executor.clone()).await?;
|
|
|
|
|
|
- self.manage_channel_for_get_info(channel).await;
|
|
|
+ self.manage_channel_for_get_info(index, channel).await;
|
|
|
|
|
|
Ok(())
|
|
|
}
|
|
|
|
|
|
- async fn manage_channel_for_get_info(&self, channel: ChannelPtr) {
|
|
|
+ async fn manage_channel_for_get_info(&self, index: usize, channel: ChannelPtr) {
|
|
|
let key = channel.address();
|
|
|
- self.connect_infos
|
|
|
- .lock()
|
|
|
- .await
|
|
|
+ self.connect_infos.lock().await[index]
|
|
|
.insert(key.clone(), InboundInfo { channel: channel.clone() });
|
|
|
|
|
|
let stop_sub = channel.subscribe_stop().await;
|
|
|
@@ -139,7 +154,7 @@ impl InboundSession {
|
|
|
stop_sub.unwrap().receive().await;
|
|
|
}
|
|
|
|
|
|
- self.connect_infos.lock().await.remove(&key);
|
|
|
+ self.connect_infos.lock().await[index].remove(&key);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -147,8 +162,9 @@ impl InboundSession {
|
|
|
impl Session for InboundSession {
|
|
|
async fn get_info(&self) -> serde_json::Value {
|
|
|
let mut infos = FxHashMap::default();
|
|
|
- if let Some(accept_addr) = self.p2p().settings().inbound.as_ref() {
|
|
|
- for (addr, info) in self.connect_infos.lock().await.iter() {
|
|
|
+ for (index, accept_addr) in self.p2p().settings().inbound.iter().enumerate() {
|
|
|
+ let connect_infos = &self.connect_infos.lock().await[index];
|
|
|
+ for (addr, info) in connect_infos {
|
|
|
let json_addr = json!({ "accept_addr": accept_addr });
|
|
|
let info = vec![json_addr, info.get_info().await];
|
|
|
infos.insert(addr.to_string(), info);
|