scatter_net/legacy/peer/methods/
ping.rs1use std::time::Duration;
2
3use chrono::TimeDelta;
4use n0_future::StreamExt;
5use tokio::time::timeout;
6
7use crate::Peer;
8
9impl Peer {
10 pub async fn ping(self, timeout_duration: Duration) -> Result<TimeDelta, PeerPingError> {
19 let mut interaction = self.begin_interaction().await?;
20
21 let time_start = chrono::Local::now();
22
23 interaction.send_packet(crate::Packet::Ping).await?;
24
25 let response = match timeout(timeout_duration, interaction.next()).await {
26 Ok(Some(result)) => result?,
27 Ok(None) => Err(PeerPingError::ConnectionClosed)?,
28 Err(_) => Err(PeerPingError::Timeout {
29 timeout_ms: timeout_duration.as_millis().try_into()?,
30 })?,
31 };
32
33 let time_end = chrono::Local::now();
34
35 match response {
36 crate::Packet::Pong => Ok(time_end - time_start),
37 packet => Err(PeerPingError::UnexpectedResponse { received: packet }),
38 }
39 }
40}
41
42#[derive(thiserror::Error, Debug)]
43pub enum PeerPingError {
44 #[error(transparent)]
45 BeginInteraction(#[from] crate::PeerBeginInteractionError),
46 #[error("Connection closed before receiving response")]
47 ConnectionClosed,
48 #[error("Reading packet failed: {0}")]
49 ReadPacket(#[from] crate::InteractionReadPacketError),
50 #[error("Sending packet failed: {0}")]
51 SendPacket(#[from] crate::InteractionSendPacketError),
52 #[error("Ping timed out after {timeout_ms}ms")]
53 Timeout { timeout_ms: u64 },
54 #[error("Expected Pong packet, received {received:?}")]
55 UnexpectedResponse { received: crate::Packet },
56 #[error(transparent)]
57 IntConversion(#[from] std::num::TryFromIntError),
58}