session.rs 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. use async_trait::async_trait;
  2. use log::*;
  3. use smol::Executor;
  4. use std::sync::Arc;
  5. use crate::net::error::NetResult;
  6. use crate::net::p2p::P2pPtr;
  7. use crate::net::protocols::ProtocolVersion;
  8. use crate::net::ChannelPtr;
  9. /// Removes channel from the list of connected channels when a stop signal is received.
  10. async fn remove_sub_on_stop(p2p: P2pPtr, channel: ChannelPtr) {
  11. debug!(target: "net", "remove_sub_on_stop() [START]");
  12. // Subscribe to stop events
  13. let stop_sub = channel.clone().subscribe_stop().await;
  14. // Wait for a stop event
  15. let _ = stop_sub.receive().await;
  16. debug!(target: "net",
  17. "remove_sub_on_stop(): received stop event. Removing channel {}",
  18. channel.address()
  19. );
  20. // Remove channel from p2p
  21. p2p.remove(channel).await;
  22. debug!(target: "net", "remove_sub_on_stop() [END]");
  23. }
  24. #[async_trait]
  25. /// Session trait. Defines methods that are used across sessions. Implements
  26. /// registering the channel and initializing the channel by performing a network
  27. /// handshake.
  28. pub trait Session: Sync {
  29. /// Registers a new channel with the session. Performs a network handshake and
  30. /// starts the channel.
  31. async fn register_channel(
  32. self: Arc<Self>,
  33. channel: ChannelPtr,
  34. executor: Arc<Executor<'_>>,
  35. ) -> NetResult<()> {
  36. debug!(target: "net", "Session::register_channel() [START]");
  37. let protocol_version = ProtocolVersion::new(channel.clone(), self.p2p().settings()).await;
  38. let handshake_task =
  39. self.perform_handshake_protocols(protocol_version, channel.clone(), executor.clone());
  40. // start channel
  41. channel.start(executor);
  42. handshake_task.await?;
  43. debug!(target: "net", "Session::register_channel() [END]");
  44. Ok(())
  45. }
  46. /// Performs network handshake to initialize channel. Adds the channel to the
  47. /// list of connected channels, and prepares to remove the channel when a stop
  48. /// signal is received.
  49. async fn perform_handshake_protocols(
  50. &self,
  51. protocol_version: Arc<ProtocolVersion>,
  52. channel: ChannelPtr,
  53. executor: Arc<Executor<'_>>,
  54. ) -> NetResult<()> {
  55. // Perform handshake
  56. protocol_version.run(executor.clone()).await?;
  57. // Channel is now initialized
  58. // Add channel to p2p
  59. self.p2p().store(channel.clone()).await;
  60. // Subscribe to stop, so can remove from p2p
  61. executor
  62. .spawn(remove_sub_on_stop(self.p2p(), channel))
  63. .detach();
  64. // Channel is ready for use
  65. Ok(())
  66. }
  67. /// Returns a pointer to the p2p network interface.
  68. fn p2p(&self) -> P2pPtr;
  69. }