|
@@ -4,14 +4,14 @@ use smol::{Async, Executor};
|
|
|
use std::net::{SocketAddr, TcpListener};
|
|
use std::net::{SocketAddr, TcpListener};
|
|
|
use std::sync::Arc;
|
|
use std::sync::Arc;
|
|
|
|
|
|
|
|
-use crate::error::{Error, Result};
|
|
|
|
|
|
|
+use crate::net::error::{NetError, NetResult};
|
|
|
use crate::net::{Channel, ChannelPtr, SettingsPtr};
|
|
use crate::net::{Channel, ChannelPtr, SettingsPtr};
|
|
|
use crate::system::{StoppableTask, StoppableTaskPtr, Subscriber, SubscriberPtr, Subscription};
|
|
use crate::system::{StoppableTask, StoppableTaskPtr, Subscriber, SubscriberPtr, Subscription};
|
|
|
|
|
|
|
|
pub type AcceptorPtr = Arc<Acceptor>;
|
|
pub type AcceptorPtr = Arc<Acceptor>;
|
|
|
|
|
|
|
|
pub struct Acceptor {
|
|
pub struct Acceptor {
|
|
|
- channel_subscriber: SubscriberPtr<Result<ChannelPtr>>,
|
|
|
|
|
|
|
+ channel_subscriber: SubscriberPtr<NetResult<ChannelPtr>>,
|
|
|
task: StoppableTaskPtr,
|
|
task: StoppableTaskPtr,
|
|
|
settings: SettingsPtr,
|
|
settings: SettingsPtr,
|
|
|
}
|
|
}
|
|
@@ -25,16 +25,15 @@ impl Acceptor {
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- pub fn accept(
|
|
|
|
|
|
|
+ pub fn start(
|
|
|
self: Arc<Self>,
|
|
self: Arc<Self>,
|
|
|
accept_addr: SocketAddr,
|
|
accept_addr: SocketAddr,
|
|
|
executor: Arc<Executor<'_>>,
|
|
executor: Arc<Executor<'_>>,
|
|
|
- ) -> Result<()> {
|
|
|
|
|
- let listener = Async::<TcpListener>::bind(accept_addr)?;
|
|
|
|
|
- info!("Listening on {}", listener.get_ref().local_addr()?);
|
|
|
|
|
|
|
+ ) -> NetResult<()> {
|
|
|
|
|
+ let listener = Self::setup(accept_addr)?;
|
|
|
|
|
|
|
|
// Start detached task and return instantly
|
|
// Start detached task and return instantly
|
|
|
- self.accept_or_stop(listener, executor);
|
|
|
|
|
|
|
+ self.accept(listener, executor);
|
|
|
|
|
|
|
|
Ok(())
|
|
Ok(())
|
|
|
}
|
|
}
|
|
@@ -44,30 +43,49 @@ impl Acceptor {
|
|
|
self.task.stop().await;
|
|
self.task.stop().await;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- fn accept_or_stop(self: Arc<Self>, listener: Async<TcpListener>, executor: Arc<Executor<'_>>) {
|
|
|
|
|
|
|
+ pub async fn subscribe(self: Arc<Self>) -> Subscription<NetResult<ChannelPtr>> {
|
|
|
|
|
+ self.channel_subscriber.clone().subscribe().await
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ fn setup(
|
|
|
|
|
+ accept_addr: SocketAddr) -> NetResult<Async<TcpListener>> {
|
|
|
|
|
+ let listener = match Async::<TcpListener>::bind(accept_addr) {
|
|
|
|
|
+ Ok(l) => l,
|
|
|
|
|
+ Err(err) => {
|
|
|
|
|
+ error!("Bind listener failed: {}", err);
|
|
|
|
|
+ return Err(NetError::OperationFailed);
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+ let local_addr = match listener.get_ref().local_addr() {
|
|
|
|
|
+ Ok(a) => a,
|
|
|
|
|
+ Err(err) => {
|
|
|
|
|
+ error!("Failed to get local address: {}", err);
|
|
|
|
|
+ return Err(NetError::OperationFailed);
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+ info!("Listening on {}", local_addr);
|
|
|
|
|
+
|
|
|
|
|
+ Ok(listener)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ fn accept(self: Arc<Self>, listener: Async<TcpListener>, executor: Arc<Executor<'_>>) {
|
|
|
self.task.clone().start(
|
|
self.task.clone().start(
|
|
|
- self.clone().run_accept(listener),
|
|
|
|
|
|
|
+ self.clone().run_accept_loop(listener),
|
|
|
|result| self.handle_stop(result),
|
|
|result| self.handle_stop(result),
|
|
|
- executor,
|
|
|
|
|
|
|
+ NetError::ServiceStopped,
|
|
|
|
|
+ executor
|
|
|
);
|
|
);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- async fn run_accept(self: Arc<Self>, listener: Async<TcpListener>) -> Result<()> {
|
|
|
|
|
|
|
+ async fn run_accept_loop(self: Arc<Self>, listener: Async<TcpListener>) -> NetResult<()> {
|
|
|
loop {
|
|
loop {
|
|
|
- match self.tick_accept(&listener).await {
|
|
|
|
|
- Ok(channel) => {
|
|
|
|
|
- let channel_result = Arc::new(Ok(channel));
|
|
|
|
|
- self.channel_subscriber.notify(channel_result).await;
|
|
|
|
|
- }
|
|
|
|
|
- Err(err) => {
|
|
|
|
|
- error!("Error listening for connections: {}", err);
|
|
|
|
|
- return Err(Error::ServiceStopped);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ let channel = self.tick_accept(&listener).await?;
|
|
|
|
|
+ let channel_result = Arc::new(Ok(channel));
|
|
|
|
|
+ self.channel_subscriber.notify(channel_result).await;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- async fn handle_stop(self: Arc<Self>, result: Result<()>) {
|
|
|
|
|
|
|
+ async fn handle_stop(self: Arc<Self>, result: NetResult<()>) {
|
|
|
match result {
|
|
match result {
|
|
|
Ok(()) => panic!("Acceptor task should never complete without error status"),
|
|
Ok(()) => panic!("Acceptor task should never complete without error status"),
|
|
|
Err(err) => {
|
|
Err(err) => {
|
|
@@ -78,8 +96,14 @@ impl Acceptor {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- async fn tick_accept(&self, listener: &Async<TcpListener>) -> Result<ChannelPtr> {
|
|
|
|
|
- let (stream, peer_addr) = listener.accept().await?;
|
|
|
|
|
|
|
+ async fn tick_accept(&self, listener: &Async<TcpListener>) -> NetResult<ChannelPtr> {
|
|
|
|
|
+ let (stream, peer_addr) = match listener.accept().await {
|
|
|
|
|
+ Ok((s, a)) => (s, a),
|
|
|
|
|
+ Err(err) => {
|
|
|
|
|
+ error!("Error listening for connections: {}", err);
|
|
|
|
|
+ return Err(NetError::ServiceStopped);
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
info!("Accepted client: {}", peer_addr);
|
|
info!("Accepted client: {}", peer_addr);
|
|
|
|
|
|
|
|
let channel = Channel::new(stream, peer_addr, self.settings.clone());
|
|
let channel = Channel::new(stream, peer_addr, self.settings.clone());
|