session.rs 3.4 KB

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