session.rs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. use async_trait::async_trait;
  2. use log::debug;
  3. use smol::Executor;
  4. use std::sync::Arc;
  5. use crate::{
  6. error::Result,
  7. net::{p2p::P2pPtr, protocol::ProtocolVersion, ChannelPtr},
  8. };
  9. /// Removes channel from the list of connected channels when a stop signal is
  10. /// received.
  11. async fn remove_sub_on_stop(p2p: P2pPtr, channel: ChannelPtr) {
  12. debug!(target: "net", "remove_sub_on_stop() [START]");
  13. // Subscribe to stop events
  14. let stop_sub = channel.clone().subscribe_stop().await;
  15. // Wait for a stop event
  16. let _ = stop_sub.receive().await;
  17. debug!(target: "net",
  18. "remove_sub_on_stop(): received stop event. Removing channel {}",
  19. channel.address()
  20. );
  21. // Remove channel from p2p
  22. p2p.remove(channel).await;
  23. debug!(target: "net", "remove_sub_on_stop() [END]");
  24. }
  25. #[async_trait]
  26. /// Session trait.
  27. pub trait Session: Sync {
  28. /// Registers a new channel with the session. Performs a network handshake
  29. /// and starts the channel.
  30. async fn register_channel(
  31. self: Arc<Self>,
  32. channel: ChannelPtr,
  33. executor: Arc<Executor<'_>>,
  34. ) -> Result<()> {
  35. debug!(target: "net", "Session::register_channel() [START]");
  36. // Protocols should all be initialized but not started
  37. // We do this so that the protocols can begin receiving and buffering messages
  38. // while the handshake protocol is ongoing.
  39. // They are currently in sleep mode.
  40. let p2p = self.p2p();
  41. let protocols =
  42. p2p.protocol_registry().attach(self.selector_id(), channel.clone(), p2p.clone()).await;
  43. // Perform the handshake protocol
  44. let protocol_version = ProtocolVersion::new(channel.clone(), self.p2p().settings()).await;
  45. let handshake_task =
  46. self.perform_handshake_protocols(protocol_version, channel.clone(), executor.clone());
  47. // Switch on the channel
  48. channel.start(executor.clone());
  49. // Wait for handshake to finish.
  50. handshake_task.await?;
  51. // Now the channel is ready
  52. debug!(target: "net", "Session handshake complete. Activating remaining protocols");
  53. // Now start all the protocols
  54. // They are responsible for managing their own lifetimes and
  55. // correctly self destructing when the channel ends.
  56. for protocol in protocols {
  57. // Activate protocol
  58. protocol.start(executor.clone()).await?;
  59. }
  60. debug!(target: "net", "Session::register_channel() [END]");
  61. Ok(())
  62. }
  63. /// Performs network handshake to initialize channel. Adds the channel to
  64. /// the list of connected channels, and prepares to remove the channel
  65. /// when a stop signal is received.
  66. async fn perform_handshake_protocols(
  67. &self,
  68. protocol_version: Arc<ProtocolVersion>,
  69. channel: ChannelPtr,
  70. executor: Arc<Executor<'_>>,
  71. ) -> Result<()> {
  72. // Perform handshake
  73. protocol_version.run(executor.clone()).await?;
  74. // Channel is now initialized
  75. // Add channel to p2p
  76. self.p2p().store(channel.clone()).await;
  77. // Subscribe to stop, so can remove from p2p
  78. executor.spawn(remove_sub_on_stop(self.p2p(), channel)).detach();
  79. // Channel is ready for use
  80. Ok(())
  81. }
  82. /// Returns a pointer to the p2p network interface.
  83. fn p2p(&self) -> P2pPtr;
  84. fn selector_id(&self) -> u32;
  85. }