acceptor.rs 4.1 KB

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