From f018b434cbc42ec45851a943d91f4b9e67f82eb8 Mon Sep 17 00:00:00 2001 From: Fintan Halpenny Date: Mon, 23 Feb 2026 22:00:59 +0000 Subject: [PATCH] node: control debug serialization of FetcherState Use proxy structs to control the serialized output of `FetcherState`. These structs convert data inside the `FetcherState` into friendlier output for the caller of `rad node debug`. --- crates/radicle-node/src/runtime/handle.rs | 96 ++++++++++++++++++----- 1 file changed, 75 insertions(+), 21 deletions(-) diff --git a/crates/radicle-node/src/runtime/handle.rs b/crates/radicle-node/src/runtime/handle.rs index 14b3eaf9..bfb7313d 100644 --- a/crates/radicle-node/src/runtime/handle.rs +++ b/crates/radicle-node/src/runtime/handle.rs @@ -356,29 +356,10 @@ impl radicle::node::Handle for Handle { fn debug(&self) -> Result { let (sender, receiver) = chan::bounded(1); let query: Arc = Arc::new(move |state| { - let fetcher_state = state.fetching(); + let fetching = debug::Fetching::new(state.fetching()); let debug = serde_json::json!({ "outboxSize": state.outbox().len(), - "fetching": fetcher_state.active_fetches() - .iter() - .map(|(rid, active)| { - json!({ - "rid": rid, - "from": active.from(), - "refsAt": active.refs(), - }) - }).collect::>(), - "queue": fetcher_state.queued_fetches().iter().map(|(node, queue)| { - json!({ - "nid": node, - "queue": queue.iter().map(|fetch| { - json!({ - "rid": fetch.rid, - "refsAt": fetch.refs, - }) - }).collect::>() - }) - }).collect::>(), + "fetching": fetching, "rateLimiter": state.limiter().buckets.iter().map(|(host, bucket)| { json!({ "host": host.to_string(), @@ -404,3 +385,76 @@ impl radicle::node::Handle for Handle { Ok(debug) } } + +mod debug { + //! Serialization formats for the output of [`Handle::debug`] output. + + use radicle_protocol::fetcher; + use radicle_protocol::fetcher::FetcherState; + use serde::Serialize; + + use super::{NodeId, RefsAt, RepoId}; + + #[derive(Serialize)] + #[serde(rename_all = "camelCase")] + pub struct Fetching { + active: Vec, + queued: Vec, + } + + impl Fetching { + pub fn new(state: &FetcherState) -> Self { + let active = state + .active_fetches() + .iter() + .map(|(rid, fetch)| ActiveFetch::new(*rid, fetch.clone())) + .collect(); + let queued = state + .queued_fetches() + .iter() + .flat_map(|(node, queue)| { + queue + .iter() + .map(|fetch| QueuedFetch::new(*node, fetch.clone())) + }) + .collect(); + Self { active, queued } + } + } + + #[derive(Serialize)] + #[serde(rename_all = "camelCase")] + pub struct ActiveFetch { + rid: RepoId, + from: NodeId, + refs_at: Vec, + } + + impl ActiveFetch { + pub fn new(rid: RepoId, fetch: fetcher::ActiveFetch) -> Self { + Self { + rid, + from: fetch.from, + refs_at: fetch.refs.into(), + } + } + } + + #[derive(Serialize)] + #[serde(rename_all = "camelCase")] + pub struct QueuedFetch { + nid: NodeId, + rid: RepoId, + refs_at: Vec, + } + + impl QueuedFetch { + pub fn new(node: NodeId, fetch: fetcher::QueuedFetch) -> Self { + Self { + nid: node, + rid: fetch.rid, + refs_at: fetch.refs.into(), + } + } + } +}