use super::Client;
#[cfg(not(target_arch = "wasm32"))]
use crate::diagnostics::DirectionalAdmissionDiagnostic;
use crate::diagnostics::{self, DiagnosticSnapshot, PeerDiagnostic};
use crate::session_token::SessionAdmission;
impl Client {
pub async fn diagnostic_snapshot(&self) -> DiagnosticSnapshot {
let peers = self.peer_sessions().await;
let omitted_peers = peers.len().saturating_sub(diagnostics::MAX_PEERS);
let peers = peers
.into_iter()
.take(diagnostics::MAX_PEERS)
.map(|peer| {
let id = peer
.active_connection_id
.as_deref()
.or_else(|| peer.candidate_connection_ids.first().map(String::as_str));
let admission = id.map(|id| self.session_admission(id));
let mut scope_kinds: Vec<_> = peer
.scopes
.iter()
.map(|s| diagnostics::scope_kind(s))
.collect();
scope_kinds.sort_unstable();
scope_kinds.dedup();
let crypto_key_installed = id.is_some_and(|id| {
self.application_crypto_key_for_connection(Some(id))
.is_some()
});
let crypto_confirmed = id.is_some_and(|id| {
self.connection_application_crypto_is_confirmed(
id,
peer.active_transport_stable_id,
)
});
#[cfg(not(target_arch = "wasm32"))]
let directional = id.zip(peer.active_transport_stable_id).map(|(id, stable)| {
let contracts = self.native_admission_stream_contracts(id);
let admission = self.session_admission(id);
let bilateral =
self.native_user_device_admission_is_bilateral(id, &admission, contracts);
DirectionalAdmissionDiagnostic {
inbound_required: bilateral || contracts.inbound.is_some(),
inbound_proven: self
.inbound_session_token_admitted_for_transport(id, stable),
outbound_required: bilateral || contracts.outbound.is_some(),
outbound_proven: self
.remote_session_token_admitted_for_transport(id, stable),
}
});
#[cfg(target_arch = "wasm32")]
let directional = None;
PeerDiagnostic {
peer_ref: diagnostics::reference(
peer.node_id.as_deref().unwrap_or(&peer.peer_id),
),
connection_ref: id.map(diagnostics::reference),
settled_ready: peer.settled_ready,
readiness_code: diagnostics::readiness_code(&peer.readiness_reason),
transport_generation: peer.transport_generation,
route_generation: peer.route_generation,
transport_stable_id: peer.active_transport_stable_id,
transport: diagnostics::transport_kind(&peer.active_transport),
scope_kinds,
admission: match admission.as_ref() {
Some(SessionAdmission::Accepted { .. }) => "accepted",
Some(SessionAdmission::Rejected { .. }) => "rejected",
Some(SessionAdmission::Pending) => "pending",
None => "unavailable",
},
authoritative_device_bound: matches!(
admission,
Some(SessionAdmission::Accepted {
authoritative_device_id: Some(_),
..
})
),
crypto_required: id
.is_some_and(|id| self.connection_requires_application_crypto(id)),
crypto_key_installed,
crypto_confirmation_required: id.is_some_and(|id| {
self.connection_requires_application_crypto_confirmation(id)
}),
crypto_confirmed,
native_directional_admission: directional,
}
})
.collect();
DiagnosticSnapshot {
schema_version: diagnostics::SCHEMA_VERSION,
sdk_version: env!("CARGO_PKG_VERSION"),
captured_at_ms: crate::coordination::now_millis_u64(),
target: if cfg!(target_arch = "wasm32") {
"wasm"
} else {
"native"
},
peers,
omitted_peers,
}
}
}