acceptor.rs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. use log::*;
  2. use smol::{Async, Executor};
  3. use std::{
  4. net::{SocketAddr, TcpListener},
  5. sync::Arc,
  6. };
  7. use crate::error::{Error, Result};
  8. //use crate::net::error::{, Result};
  9. use crate::{
  10. net::{Channel, ChannelPtr},
  11. system::{StoppableTask, StoppableTaskPtr, Subscriber, SubscriberPtr, Subscription},
  12. };
  13. /// Atomic pointer to Acceptor class.
  14. pub type AcceptorPtr = Arc<Acceptor>;
  15. /// Create inbound socket connections.
  16. pub struct Acceptor {
  17. channel_subscriber: SubscriberPtr<Result<ChannelPtr>>,
  18. task: StoppableTaskPtr,
  19. }
  20. impl Acceptor {
  21. /// Create new Acceptor object.
  22. pub fn new() -> Arc<Self> {
  23. Arc::new(Self { channel_subscriber: Subscriber::new(), task: StoppableTask::new() })
  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. ) -> Result<()> {
  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<Result<ChannelPtr>> {
  45. self.channel_subscriber.clone().subscribe().await
  46. }
  47. /// Start listening on a local socket address.
  48. fn setup(accept_addr: SocketAddr) -> Result<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(Error::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(Error::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. Error::ServiceStopped,
  73. executor,
  74. );
  75. }
  76. /// Run the accept loop.
  77. async fn run_accept_loop(self: Arc<Self>, listener: Async<TcpListener>) -> Result<()> {
  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: Result<()>) {
  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>) -> Result<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(Error::ServiceStopped)
  103. }
  104. };
  105. info!("Accepted client: {}", peer_addr);
  106. let channel = Channel::new(stream, peer_addr).await;
  107. Ok(channel)
  108. }
  109. }