acceptor.rs 4.0 KB

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