acceptor.rs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. use log::*;
  2. use smol::{Async, Executor};
  3. use std::net::{SocketAddr, TcpListener};
  4. use std::sync::Arc;
  5. use crate::net::error::{NetError, NetResult};
  6. use crate::net::{Channel, ChannelPtr};
  7. use crate::system::{StoppableTask, StoppableTaskPtr, Subscriber, SubscriberPtr, Subscription};
  8. /// Atomic pointer to Acceptor class.
  9. pub type AcceptorPtr = Arc<Acceptor>;
  10. /// Handles the acceptance of inbound socket connections. Used to start listening
  11. /// on a local socket address, to accept incoming connections and to handle network errors.
  12. pub struct Acceptor {
  13. channel_subscriber: SubscriberPtr<NetResult<ChannelPtr>>,
  14. task: StoppableTaskPtr,
  15. }
  16. impl Acceptor {
  17. /// Create new Acceptor object.
  18. pub fn new() -> Arc<Self> {
  19. Arc::new(Self {
  20. channel_subscriber: Subscriber::new(),
  21. task: StoppableTask::new(),
  22. })
  23. }
  24. /// Start accepting inbound socket connections. Creates a listener to start
  25. /// listening on a local socket address. Then runs an accept loop in a new
  26. /// thread, erroring if a connection problem occurs.
  27. pub fn start(
  28. self: Arc<Self>,
  29. accept_addr: SocketAddr,
  30. executor: Arc<Executor<'_>>,
  31. ) -> NetResult<()> {
  32. let listener = Self::setup(accept_addr)?;
  33. // Start detached task and return instantly
  34. self.accept(listener, executor);
  35. Ok(())
  36. }
  37. /// Stop accepting inbound socket connections.
  38. pub async fn stop(&self) {
  39. // Send stop signal
  40. self.task.stop().await;
  41. }
  42. /// Start receiving network messages.
  43. pub async fn subscribe(self: Arc<Self>) -> Subscription<NetResult<ChannelPtr>> {
  44. self.channel_subscriber.clone().subscribe().await
  45. }
  46. /// Start listening on a local socket address.
  47. fn setup(accept_addr: SocketAddr) -> NetResult<Async<TcpListener>> {
  48. let listener = match Async::<TcpListener>::bind(accept_addr) {
  49. Ok(listener) => listener,
  50. Err(err) => {
  51. error!("Bind listener failed: {}", err);
  52. return Err(NetError::OperationFailed);
  53. }
  54. };
  55. let local_addr = match listener.get_ref().local_addr() {
  56. Ok(addr) => addr,
  57. Err(err) => {
  58. error!("Failed to get local address: {}", err);
  59. return Err(NetError::OperationFailed);
  60. }
  61. };
  62. info!("Listening on {}", local_addr);
  63. Ok(listener)
  64. }
  65. /// Run the accept loop in a new thread and error if a connection problem occurs.
  66. fn accept(self: Arc<Self>, listener: Async<TcpListener>, executor: Arc<Executor<'_>>) {
  67. self.task.clone().start(
  68. self.clone().run_accept_loop(listener),
  69. |result| self.handle_stop(result),
  70. NetError::ServiceStopped,
  71. executor,
  72. );
  73. }
  74. /// Run the accept loop.
  75. async fn run_accept_loop(self: Arc<Self>, listener: Async<TcpListener>) -> NetResult<()> {
  76. loop {
  77. let channel = self.tick_accept(&listener).await?;
  78. self.channel_subscriber.notify(Ok(channel)).await;
  79. }
  80. }
  81. /// Handles network errors. Panics if error passes silently, otherwise broadcasts the error.
  82. async fn handle_stop(self: Arc<Self>, result: NetResult<()>) {
  83. match result {
  84. Ok(()) => panic!("Acceptor task should never complete without error status"),
  85. Err(err) => {
  86. // Send this error to all channel subscribers
  87. let result = Err(err);
  88. self.channel_subscriber.notify(result).await;
  89. }
  90. }
  91. }
  92. /// Single attempt to accept an incoming connection. Stops after one attempt.
  93. async fn tick_accept(&self, listener: &Async<TcpListener>) -> NetResult<ChannelPtr> {
  94. let (stream, peer_addr) = match listener.accept().await {
  95. Ok((s, a)) => (s, a),
  96. Err(err) => {
  97. error!("Error listening for connections: {}", err);
  98. return Err(NetError::ServiceStopped);
  99. }
  100. };
  101. info!("Accepted client: {}", peer_addr);
  102. let channel = Channel::new(stream, peer_addr).await;
  103. Ok(channel)
  104. }
  105. }