From ce0b13e9149282be8218c4db33ef49e97bd948b2 Mon Sep 17 00:00:00 2001 From: Jay Date: Tue, 19 May 2026 13:47:17 -0400 Subject: [PATCH] feat: add peerstat package with Sink interface and NoopSink --- peerstat/sink.go | 19 +++++++++++++++++++ peerstat/sink_test.go | 17 +++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 peerstat/sink.go create mode 100644 peerstat/sink_test.go diff --git a/peerstat/sink.go b/peerstat/sink.go new file mode 100644 index 0000000..35694e6 --- /dev/null +++ b/peerstat/sink.go @@ -0,0 +1,19 @@ +// Package peerstat defines the contract for collecting peer-level statistics. +package peerstat + +// Sink is the interface through which add-ons report statistics. +// Add-ons should call Record() with a peer ID and a typed event when +// significant events occur. The event parameter is expected to be a +// domain-specific struct defined in the add-on's package. +type Sink interface { + // Record reports a statistic event for a given peer. + // The event parameter contains the domain-specific details. + Record(peerID string, event any) +} + +// NoopSink is a null implementation of Sink that does nothing. +// It is used when no actual statistics collector is wired in. +type NoopSink struct{} + +// Record implements Sink for NoopSink, doing nothing. +func (NoopSink) Record(_ string, _ any) {} diff --git a/peerstat/sink_test.go b/peerstat/sink_test.go new file mode 100644 index 0000000..5fc8390 --- /dev/null +++ b/peerstat/sink_test.go @@ -0,0 +1,17 @@ +package peerstat + +import ( + "testing" +) + +func TestNoopSink(t *testing.T) { + // Test that NoopSink implements the Sink interface + var _ Sink = NoopSink{} + + // Test that calling Record doesn't panic or crash + sink := NoopSink{} + sink.Record("peer1", "test event") + sink.Record("", nil) + + // Test that it's a no-op (no assertions needed since it does nothing) +}