From cae4488c06f3726e5b72f62ea0190469b266d9e5 Mon Sep 17 00:00:00 2001 From: Chris O'Neil Date: Tue, 12 May 2026 17:22:07 +0100 Subject: [PATCH] feat(chunk-get): emit per-failure close-group summary at info level When chunk_get exhausts its close group without finding the chunk, emit a single info-level summary line covering the count of peers queried and the per-peer terminal outcome (NotFound / Timeout / Network error). Motivation: when a client reports "Chunk not found", the existing per-peer debug lines don't tell operators (or downstream tooling) whether the cause was genuine data loss (every close-group peer responded NotFound) or a reachability problem from the client's vantage (peers timed out before responding). The summary line surfaces that distinction in a single greppable line at -v (info) verbosity, so it doesn't require -vv debug logs to recover after the fact. Co-Authored-By: Claude Opus 4.7 (1M context) --- ant-core/src/data/client/chunk.rs | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/ant-core/src/data/client/chunk.rs b/ant-core/src/data/client/chunk.rs index dab11a8..ad03d69 100644 --- a/ant-core/src/data/client/chunk.rs +++ b/ant-core/src/data/client/chunk.rs @@ -16,7 +16,7 @@ use bytes::Bytes; use futures::stream::{FuturesUnordered, StreamExt}; use std::future::Future; use std::time::{Duration, Instant}; -use tracing::{debug, warn}; +use tracing::{debug, info, warn}; /// Data type identifier for chunks (used in quote requests). const CHUNK_DATA_TYPE: u32 = 0; @@ -254,6 +254,11 @@ impl Client { let peers = self.close_group_peers(address).await?; let addr_hex = hex::encode(address); + let queried = peers.len(); + let mut not_found = 0usize; + let mut timeout = 0usize; + let mut network_err = 0usize; + for (peer, addrs) in &peers { match self.chunk_get_from_peer(address, peer, addrs).await { Ok(Some(chunk)) => { @@ -261,16 +266,28 @@ impl Client { return Ok(Some(chunk)); } Ok(None) => { + not_found += 1; debug!("Chunk {addr_hex} not found on peer {peer}, trying next"); } - Err(Error::Timeout(_) | Error::Network(_)) => { + Err(Error::Timeout(_)) => { + timeout += 1; + debug!("Peer {peer} timed out for chunk {addr_hex}, trying next"); + } + Err(Error::Network(_)) => { + network_err += 1; debug!("Peer {peer} unreachable for chunk {addr_hex}, trying next"); } Err(e) => return Err(e), } } - // None of the close group peers had the chunk + // None of the close group peers had the chunk. Emit a single summary + // so operators can distinguish data loss (all peers responded NotFound) + // from a reachability problem (most peers timed out / errored). + info!( + "chunk_get exhausted close group for {addr_hex}: \ + queried={queried} not_found={not_found} timeout={timeout} network_err={network_err}" + ); Ok(None) }