Skip to content

feat: add cumulative replication traffic accounting - #172

Merged
jacderida merged 1 commit into
WithAutonomi:mainfrom
jacderida:feat/v2-623-traffic-accounting
Jul 12, 2026
Merged

feat: add cumulative replication traffic accounting#172
jacderida merged 1 commit into
WithAutonomi:mainfrom
jacderida:feat/v2-623-traffic-accounting

Conversation

@jacderida

Copy link
Copy Markdown
Member

Summary

Part of V2-623 (log-based traffic accounting). Chunk fetch/offer and
replication payloads are invisible in the logs today. This adds cumulative,
monotonic per-variant byte/message counters as INFO summary lines so the
telegraf→Elasticsearch pipeline can attribute how much bandwidth each
replication message type moves, per direction.
Purely additive: no wire changes, no behaviour changes.

  • A process-global per-variant counter table in the replication protocol module
    (relaxed atomics), incremented at the single encode (tx) and decode (rx)
    choke points that every replication message passes through.
  • New replication traffic summary (cumulative) INFO lines (target
    ant_node::replication::traffic) from a periodic task in the replication
    engine.

Note on line splitting: the 17 variants × 4 flat keys (68) exceed
tracing's 32-field event cap, so the flat keys (fresh_offer_tx_bytes, …) are
split across three lines sharing the same target and message and distinguished
by a group field. The shipping pipeline lifts each key into its own field, so
the acceptance query (max per field per hour → delta → per-variant MB/h) is
unaffected.

Test plan

  • cargo check (default features)
  • cargo check --no-default-features (logging compiled out)
  • cargo clippy --all-features -- -D warnings -D clippy::panic -D clippy::unwrap_used -D clippy::expect_used
  • cargo fmt --all -- --check

🤖 Generated with Claude Code

The 2026-07-09 production bandwidth diagnosis (V2-623) found chunk fetch/offer
and replication payloads invisible in the logs. Add cumulative, monotonic
per-variant byte/message counters surfaced as INFO summary lines so the
telegraf->Elasticsearch pipeline can attribute how much bandwidth each
replication message type moves, per direction. Purely additive: no wire
changes, no behaviour changes.

- Add a process-global per-variant counter table in the replication protocol
  module (relaxed atomics), incremented at the single encode (tx) and decode
  (rx) choke points that every replication message passes through.
- Emit replication traffic summary (cumulative) INFO lines
  (target ant_node::replication::traffic) from a new periodic task in the
  replication engine. The 17 variants x 4 flat keys exceed tracing's 32-field
  event cap, so the flat keys are split across three lines sharing the same
  target and message; the shipping pipeline lifts each into its own field.

Verified: cargo check (default and --no-default-features), cargo fmt --all,
cargo clippy --all-features -D warnings -D clippy::panic -D clippy::unwrap_used
-D clippy::expect_used all clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 10, 2026 23:47

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds process-wide, cumulative per-ReplicationMessageBody traffic counters and periodically emits INFO summary lines so the logging pipeline can attribute replication bandwidth by message type and direction (tx/rx), without changing wire format or runtime behavior.

Changes:

  • Increment per-variant tx/rx byte + message counters at the ReplicationMessage::encode / decode choke points.
  • Add a process-global relaxed-atomic counter table and a log_traffic_summary() emitter that splits fields across 3 tracing events.
  • Start a new periodic background task in the replication engine to emit the cumulative summaries.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/replication/protocol.rs Adds global relaxed-atomic counter tables, per-variant indexing, and INFO summary logging; hooks tx/rx accounting into encode/decode.
src/replication/mod.rs Adds a periodic background task that emits the traffic summary at a fixed cadence.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +211 to +222
fn record_tx(body: &ReplicationMessageBody, bytes: usize) {
let i = body.variant_index();
REPL_TX_BYTES[i].fetch_add(bytes as u64, Ordering::Relaxed);
REPL_TX_COUNT[i].fetch_add(1, Ordering::Relaxed);
}

/// Record a decoded (rx) replication message against its variant.
fn record_rx(body: &ReplicationMessageBody, bytes: usize) {
let i = body.variant_index();
REPL_RX_BYTES[i].fetch_add(bytes as u64, Ordering::Relaxed);
REPL_RX_COUNT[i].fetch_add(1, Ordering::Relaxed);
}
Comment on lines 54 to +86
@@ -70,8 +76,14 @@ impl ReplicationMessage {
max_size: MAX_REPLICATION_MESSAGE_SIZE,
});
}
postcard::from_bytes(data)
.map_err(|e| ReplicationProtocolError::DeserializationFailed(e.to_string()))
let message: Self = postcard::from_bytes(data)
.map_err(|e| ReplicationProtocolError::DeserializationFailed(e.to_string()))?;

// V2-623: cumulative per-variant rx accounting. Every replication
// receive funnels through here, so this is the single rx choke point.
record_rx(&message.body, data.len());

Ok(message)
Comment thread src/replication/mod.rs
Comment on lines +1440 to +1453
let shutdown = self.shutdown.clone();
let handle = tokio::spawn(async move {
loop {
tokio::select! {
() = shutdown.cancelled() => break,
() = tokio::time::sleep(std::time::Duration::from_secs(
TRAFFIC_SUMMARY_INTERVAL_SECS,
)) => {
protocol::log_traffic_summary();
}
}
}
debug!("Replication traffic summary loop shut down");
});

@dirvine dirvine left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hermes review — conditionally ready after CI and ingestion smoke test

No wire-format or replication-behaviour change found. The encode/decode accounting is internally consistent, and local cargo check plus cargo check --no-default-features passed at head a86521345d8cdd63d795537765f341610532122a.

Caveats:

  • TX counters measure successfully encoded replication messages, not confirmed network sends. Failed sends/retries can therefore exceed actual egress. Please name/document these as encoded/attempted traffic unless accounting is moved to the send-success path.
  • The fixed 17-variant index/table is currently exhaustive and in bounds, but future enum/table drift could panic. A focused test asserting unique in-range indices and coverage of all emitted groups would cheaply guard this.
  • The three sparse INFO events are workable for per-field cumulative queries, but please verify all three groups and all 68 fields survive the real Telegraf/Elasticsearch pipeline.

Current CI: format, Clippy, docs, security audit, no-logging test, and Linux/macOS builds pass; Windows build and platform tests are still pending.

Recommendation: no code-level production blocker found for diagnostic use, subject to all required CI completing green and one >5-minute ingestion smoke test. Not approved yet while CI is pending.

@dirvine dirvine left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow-up approval

No code-level blocker found at head a86521345d8cdd63d795537765f341610532122a.

The counters consistently measure successfully encoded/decoded replication protocol traffic. TX is encoded/attempted volume rather than confirmed network delivery; that is acceptable for diagnostic use provided the query retains that interpretation.

Format, Clippy, documentation, security audit, no-logging and all platform builds are green. macOS and Windows tests were still pending at the latest check; approval does not waive those required jobs.

A Telegraf/Elasticsearch smoke test is optional canary validation of the three grouped events and field mappings, not a code-safety gate.

@jacderida
jacderida merged commit bc4c448 into WithAutonomi:main Jul 12, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants