acceptor.rs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. use std::sync::Arc;
  2. use smol::Executor;
  3. use url::Url;
  4. use crate::{
  5. system::{StoppableTask, StoppableTaskPtr, Subscriber, SubscriberPtr, Subscription},
  6. Error, Result,
  7. };
  8. use super::{Channel, ChannelPtr, Transport};
  9. /// Atomic pointer to Acceptor class.
  10. pub type AcceptorPtr<T> = Arc<Acceptor<T>>;
  11. /// Create inbound socket connections.
  12. pub struct Acceptor<T: Transport> {
  13. channel_subscriber: SubscriberPtr<Result<ChannelPtr<T>>>,
  14. task: StoppableTaskPtr,
  15. }
  16. impl<T: Transport> Acceptor<T> {
  17. /// Create new Acceptor object.
  18. pub fn new() -> Arc<Self> {
  19. Arc::new(Self { channel_subscriber: Subscriber::new(), task: StoppableTask::new() })
  20. }
  21. /// Start accepting inbound socket connections. Creates a listener to start
  22. /// listening on a local socket address. Then runs an accept loop in a new
  23. /// thread, erroring if a connection problem occurs.
  24. pub async fn start(
  25. self: Arc<Self>,
  26. accept_addr: Url,
  27. executor: Arc<Executor<'_>>,
  28. ) -> Result<()> {
  29. self.accept(accept_addr, executor);
  30. Ok(())
  31. }
  32. /// Stop accepting inbound socket connections.
  33. pub async fn stop(&self) {
  34. // Send stop signal
  35. self.task.stop().await;
  36. }
  37. /// Start receiving network messages.
  38. pub async fn subscribe(self: Arc<Self>) -> Subscription<Result<ChannelPtr<T>>> {
  39. self.channel_subscriber.clone().subscribe().await
  40. }
  41. /// Run the accept loop in a new thread and error if a connection problem
  42. /// occurs.
  43. fn accept(self: Arc<Self>, url: Url, executor: Arc<Executor<'_>>) {
  44. self.task.clone().start(
  45. self.clone().run_accept_loop(url),
  46. |result| self.handle_stop(result),
  47. Error::ServiceStopped,
  48. executor,
  49. );
  50. }
  51. /// Run the accept loop.
  52. async fn run_accept_loop(self: Arc<Self>, url: url::Url) -> Result<()> {
  53. let transport = T::new(None, 1024);
  54. let listener = Arc::new(transport.listen_on(url.clone())?.await?);
  55. loop {
  56. let stream = T::accept(listener.clone()).await?;
  57. let channel = Channel::<T>::new(stream, url.clone()).await;
  58. self.channel_subscriber.notify(Ok(channel)).await;
  59. }
  60. }
  61. /// Handles network errors. Panics if error passes silently, otherwise
  62. /// broadcasts the error.
  63. async fn handle_stop(self: Arc<Self>, result: Result<()>) {
  64. match result {
  65. Ok(()) => panic!("Acceptor task should never complete without error status"),
  66. Err(err) => {
  67. // Send this error to all channel subscribers
  68. let result = Err(err);
  69. self.channel_subscriber.notify(result).await;
  70. }
  71. }
  72. }
  73. }