acceptor.rs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. use log::*;
  2. use smol::{Async, Executor};
  3. use std::net::{SocketAddr, TcpListener};
  4. use std::sync::Arc;
  5. use crate::error::{Error, Result};
  6. //use crate::net::error::{, Result};
  7. use crate::net::{Channel, ChannelPtr};
  8. use crate::system::{StoppableTask, StoppableTaskPtr, Subscriber, SubscriberPtr, Subscription};
  9. /// Atomic pointer to Acceptor class.
  10. pub type AcceptorPtr = Arc<Acceptor>;
  11. /// Create inbound socket connections.
  12. pub struct Acceptor {
  13. channel_subscriber: SubscriberPtr<Result<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. ) -> Result<()> {
  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<Result<ChannelPtr>> {
  44. self.channel_subscriber.clone().subscribe().await
  45. }
  46. /// Start listening on a local socket address.
  47. fn setup(accept_addr: SocketAddr) -> Result<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(Error::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(Error::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
  66. /// occurs.
  67. fn accept(self: Arc<Self>, listener: Async<TcpListener>, executor: Arc<Executor<'_>>) {
  68. self.task.clone().start(
  69. self.clone().run_accept_loop(listener),
  70. |result| self.handle_stop(result),
  71. Error::ServiceStopped,
  72. executor,
  73. );
  74. }
  75. /// Run the accept loop.
  76. async fn run_accept_loop(self: Arc<Self>, listener: Async<TcpListener>) -> Result<()> {
  77. loop {
  78. let channel = self.tick_accept(&listener).await?;
  79. self.channel_subscriber.notify(Ok(channel)).await;
  80. }
  81. }
  82. /// Handles network errors. Panics if error passes silently, otherwise
  83. /// broadcasts the error.
  84. async fn handle_stop(self: Arc<Self>, result: Result<()>) {
  85. match result {
  86. Ok(()) => panic!("Acceptor task should never complete without error status"),
  87. Err(err) => {
  88. // Send this error to all channel subscribers
  89. let result = Err(err);
  90. self.channel_subscriber.notify(result).await;
  91. }
  92. }
  93. }
  94. /// Single attempt to accept an incoming connection. Stops after one
  95. /// attempt.
  96. async fn tick_accept(&self, listener: &Async<TcpListener>) -> Result<ChannelPtr> {
  97. let (stream, peer_addr) = match listener.accept().await {
  98. Ok((s, a)) => (s, a),
  99. Err(err) => {
  100. error!("Error listening for connections: {}", err);
  101. return Err(Error::ServiceStopped);
  102. }
  103. };
  104. info!("Accepted client: {}", peer_addr);
  105. let channel = Channel::new(stream, peer_addr).await;
  106. Ok(channel)
  107. }
  108. }