Revert "node/debug: Use derived serializers"

This reverts commit 5099c25df7.

The `HostName` of the `RateLimiter` could serialize as an invalid JSON
key, resulting in the command panicking.
This commit is contained in:
Fintan Halpenny 2026-02-23 21:49:34 +00:00 committed by Lorenz Leutgeb
parent e9245b630d
commit 9ea1ea2433
3 changed files with 34 additions and 12 deletions

View File

@ -356,10 +356,35 @@ impl radicle::node::Handle for Handle {
fn debug(&self) -> Result<serde_json::Value, Self::Error> { fn debug(&self) -> Result<serde_json::Value, Self::Error> {
let (sender, receiver) = chan::bounded(1); let (sender, receiver) = chan::bounded(1);
let query: Arc<QueryState> = Arc::new(move |state| { let query: Arc<QueryState> = Arc::new(move |state| {
let fetcher_state = state.fetching();
let debug = serde_json::json!({ let debug = serde_json::json!({
"outboxSize": state.outbox().len(), "outboxSize": state.outbox().len(),
"fetching": state.fetching(), "fetching": fetcher_state.active_fetches()
"rateLimiter": state.limiter(), .iter()
.map(|(rid, active)| {
json!({
"rid": rid,
"from": active.from(),
"refsAt": active.refs(),
})
}).collect::<Vec<_>>(),
"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::<Vec<_>>()
})
}).collect::<Vec<_>>(),
"rateLimiter": state.limiter().buckets.iter().map(|(host, bucket)| {
json!({
"host": host.to_string(),
"bucket": bucket
})
}).collect::<Vec<_>>(),
"events": json!({ "events": json!({
"subscribers": state.emitter().subscriptions(), "subscribers": state.emitter().subscriptions(),
"pending": state.emitter().pending(), "pending": state.emitter().pending(),

View File

@ -10,7 +10,6 @@ pub mod event;
pub use command::Command; pub use command::Command;
pub use event::Event; pub use event::Event;
use serde::Serialize;
use std::collections::{BTreeMap, VecDeque}; use std::collections::{BTreeMap, VecDeque};
use std::num::NonZeroUsize; use std::num::NonZeroUsize;
@ -43,7 +42,7 @@ pub const MAX_CONCURRENCY: NonZeroUsize = NonZeroUsize::MIN;
/// of fetches can happen with it concurrently. This does not guarantee that the /// of fetches can happen with it concurrently. This does not guarantee that the
/// node will actually allow this node to fetch from it since it will maintain /// node will actually allow this node to fetch from it since it will maintain
/// its own capacity for connections and load. /// its own capacity for connections and load.
#[derive(Clone, Debug, PartialEq, Eq, Serialize)] #[derive(Clone, Debug, PartialEq, Eq)]
pub struct FetcherState { pub struct FetcherState {
/// The active fetches that are occurring, ensuring only one fetch per repository. /// The active fetches that are occurring, ensuring only one fetch per repository.
active: BTreeMap<RepoId, ActiveFetch>, active: BTreeMap<RepoId, ActiveFetch>,
@ -236,7 +235,7 @@ impl FetcherState {
} }
/// Configuration for the [`FetcherState`]. /// Configuration for the [`FetcherState`].
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Config { pub struct Config {
/// Maximum number of concurrent fetches per peer connection. /// Maximum number of concurrent fetches per peer connection.
maximum_concurrency: NonZeroUsize, maximum_concurrency: NonZeroUsize,
@ -272,7 +271,7 @@ impl Default for Config {
} }
/// An active fetch represents a repository being fetched by a particular node. /// An active fetch represents a repository being fetched by a particular node.
#[derive(Clone, Debug, PartialEq, Eq, Serialize)] #[derive(Clone, Debug, PartialEq, Eq)]
pub struct ActiveFetch { pub struct ActiveFetch {
pub from: NodeId, pub from: NodeId,
pub refs: RefsToFetch, pub refs: RefsToFetch,
@ -291,7 +290,7 @@ impl ActiveFetch {
} }
/// A fetch that is waiting to be processed, in the fetch queue. /// A fetch that is waiting to be processed, in the fetch queue.
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct QueuedFetch { pub struct QueuedFetch {
/// The repository that will be fetched. /// The repository that will be fetched.
pub rid: RepoId, pub rid: RepoId,
@ -305,15 +304,14 @@ pub struct QueuedFetch {
/// ///
/// It ensures that the queue contains unique items for fetching, and does not /// It ensures that the queue contains unique items for fetching, and does not
/// exceed the provided maximum capacity. /// exceed the provided maximum capacity.
#[derive(Clone, Debug, PartialEq, Eq, Serialize)] #[derive(Clone, Debug, PartialEq, Eq)]
pub struct Queue { pub struct Queue {
queue: VecDeque<QueuedFetch>, queue: VecDeque<QueuedFetch>,
max_queue_size: MaxQueueSize, max_queue_size: MaxQueueSize,
} }
/// The maximum number of fetches that can be queued for a single node. /// The maximum number of fetches that can be queued for a single node.
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)] #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[serde(transparent)]
pub struct MaxQueueSize(usize); pub struct MaxQueueSize(usize);
impl MaxQueueSize { impl MaxQueueSize {

View File

@ -2,7 +2,6 @@ use std::collections::{HashMap, HashSet};
use localtime::LocalTime; use localtime::LocalTime;
use radicle::node::{address, config, HostName, NodeId}; use radicle::node::{address, config, HostName, NodeId};
use serde::Serialize;
/// Peer rate limiter. /// Peer rate limiter.
/// ///
@ -10,7 +9,7 @@ use serde::Serialize;
/// and every request from that address consumes one token. Tokens refill at a predefined /// and every request from that address consumes one token. Tokens refill at a predefined
/// rate. This mechanism allows for consistent request rates with potential bursts up to the /// rate. This mechanism allows for consistent request rates with potential bursts up to the
/// bucket's capacity. /// bucket's capacity.
#[derive(Debug, Default, Serialize)] #[derive(Debug, Default)]
pub struct RateLimiter { pub struct RateLimiter {
pub buckets: HashMap<HostName, TokenBucket>, pub buckets: HashMap<HostName, TokenBucket>,
pub bypass: HashSet<NodeId>, pub bypass: HashSet<NodeId>,