use std::num::NonZeroUsize;
use super::delivery::record_measurement;
use super::PendingConnectionAttempt;
use super::SwarmTransport;
use crate::dht::Did;
use crate::measure::order_peers_by_quality;
use crate::measure::Authentication;
use crate::measure::MeasurementEvent;
use crate::measure::PeerMeasurement;
use crate::measure::PeerMeasurementPage;
use crate::measure::PeerQuality;
impl SwarmTransport {
pub(super) async fn record_peer_measurement(
&self,
peer: Did,
authentication: Authentication,
event: MeasurementEvent,
) {
record_measurement(self.measure.clone(), peer, authentication, event).await;
}
pub(crate) async fn record_peer_message_received(
&self,
attempt: PendingConnectionAttempt,
authentication: Authentication,
useful_bytes: u64,
) {
if matches!(authentication, Authentication::Authenticated) {
self.mark_peer_liveness_inbound(attempt);
}
self.record_peer_measurement(attempt.peer, authentication, MeasurementEvent::Received {
useful_bytes,
})
.await;
}
pub(crate) async fn record_peer_message_receive_failed(
&self,
peer: Did,
authentication: Authentication,
) {
self.record_peer_measurement(peer, authentication, MeasurementEvent::FailedToReceive)
.await;
}
pub(crate) async fn record_peer_message_send_failed(
&self,
peer: Did,
authentication: Authentication,
) {
self.record_peer_measurement(peer, authentication, MeasurementEvent::FailedToSend)
.await;
}
pub(crate) async fn peer_quality(&self, peer: Did) -> PeerQuality {
match &self.measure {
Some(measure) => measure.quality(peer).await,
None => PeerQuality::Unknown,
}
}
pub(crate) async fn peer_measurement(&self, peer: Did) -> Option<PeerMeasurement> {
match &self.measure {
Some(measure) => match measure.peer_measurement(peer).await {
Ok(measurement) => measurement,
Err(error) => {
tracing::error!(peer = %peer, %error, "failed to project peer measurement");
None
}
},
None => None,
}
}
pub(crate) async fn peer_measurements(&self) -> Vec<PeerMeasurement> {
match &self.measure {
Some(measure) => match measure.peer_measurements().await {
Ok(measurements) => measurements,
Err(error) => {
tracing::error!(%error, "failed to project peer measurements");
Vec::new()
}
},
None => Vec::new(),
}
}
pub(crate) async fn peer_measurements_page(
&self,
after: Option<Did>,
limit: NonZeroUsize,
) -> PeerMeasurementPage {
match &self.measure {
Some(measure) => match measure.peer_measurements_page(after, limit).await {
Ok(page) => page,
Err(error) => {
tracing::error!(%error, "failed to project peer measurement page");
PeerMeasurementPage::default()
}
},
None => PeerMeasurementPage::default(),
}
}
pub(crate) async fn order_dht_candidates_by_quality(
&self,
candidates: impl IntoIterator<Item = Did>,
) -> Vec<Did> {
let mut measured = Vec::new();
for did in candidates {
measured.push((did, self.peer_quality(did).await));
}
order_peers_by_quality(measured)
}
}