summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-12 23:16:46 +0300
committerPaul Buetow <paul@buetow.org>2026-05-12 23:16:46 +0300
commit119c679dd16d6a3c89b9d37665c44815956b6f82 (patch)
treecdff21d863f689b7fb0b350d448021fd3a2481be
parent0a342e08ebcc475524582260ab05841adf111596 (diff)
add compile-time interface satisfaction assertions for public types
Add var _ Interface = (*ConcreteType)(nil) assertions for: - *flamegraph.LiveTrie → runtime.{Snapshotter,Configurator,LiveTrieSource} and tui/flamegraph.{Snapshotter,Configurator,LiveTrieSource} - *probemanager.Manager → runtime.ProbeManager - *statsengine.Engine → runtime.SnapshotSource - *streamrow.RingBuffer → runtime.EventSink - *runtimeBindings (tui) → runtime.TraceRuntimeBindings - *lateBoundDashboardSource → dashboard.SnapshotSource - libbpfTracepointProgram/Module → probemanager.{Program,Attacher} Assertions are grouped close to their interface definitions to avoid introducing new import cycles (runtime already imports all affected packages; tui/flamegraph already imports coreflamegraph). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
-rw-r--r--internal/ior_bpfsetup.go13
-rw-r--r--internal/runtime/runtime.go28
-rw-r--r--internal/tui/flamegraph/model.go13
-rw-r--r--internal/tui/tui.go17
4 files changed, 71 insertions, 0 deletions
diff --git a/internal/ior_bpfsetup.go b/internal/ior_bpfsetup.go
index d5f3be8..885d321 100644
--- a/internal/ior_bpfsetup.go
+++ b/internal/ior_bpfsetup.go
@@ -97,3 +97,16 @@ func setupEventChannel(bpfModule *bpf.Module) (chan []byte, error) {
rb.Poll(300)
return ch, nil
}
+
+// --- compile-time interface satisfaction assertions ---
+//
+// These blank-identifier assignments cause a build error if the libbpf wrapper
+// types drift out of sync with the probemanager interfaces they satisfy.
+
+var (
+ // libbpfTracepointProgram wraps a *bpf.BPFProg as a probemanager.Program.
+ _ probemanager.Program = (*libbpfTracepointProgram)(nil)
+
+ // libbpfTracepointModule wraps a *bpf.Module as a probemanager.Attacher.
+ _ probemanager.Attacher = (*libbpfTracepointModule)(nil)
+)
diff --git a/internal/runtime/runtime.go b/internal/runtime/runtime.go
index 5e6f2a4..307c012 100644
--- a/internal/runtime/runtime.go
+++ b/internal/runtime/runtime.go
@@ -186,3 +186,31 @@ func TraceFiltersFromContext(ctx context.Context) (globalfilter.Filter, bool) {
}
return filters.filter.Clone(), true
}
+
+// --- compile-time interface satisfaction assertions ---
+//
+// These blank-identifier assignments cause a build error if any concrete type
+// drifts out of sync with the interface it claims to satisfy. They are grouped
+// here because the runtime package already imports every relevant package
+// (*flamegraph.LiveTrie, *probemanager.Manager, *statsengine.Engine, and
+// *streamrow.RingBuffer), keeping the assertions co-located with the interface
+// definitions without introducing new import cycles.
+
+var (
+ // *flamegraph.LiveTrie must satisfy both the read-only and mutating sides of
+ // the trie contract as well as the combined LiveTrieSource interface.
+ _ Snapshotter = (*flamegraph.LiveTrie)(nil)
+ _ Configurator = (*flamegraph.LiveTrie)(nil)
+ _ LiveTrieSource = (*flamegraph.LiveTrie)(nil)
+
+ // *probemanager.Manager must satisfy the probe-control surface exposed to the TUI.
+ _ ProbeManager = (*probemanager.Manager)(nil)
+
+ // *statsengine.Engine must satisfy the snapshot-source contract used by the
+ // dashboard and the TUI runtime.
+ _ SnapshotSource = (*statsengine.Engine)(nil)
+
+ // *streamrow.RingBuffer must satisfy the full event-sink contract (read +
+ // write sides), which is a superset of StreamSource.
+ _ EventSink = (*streamrow.RingBuffer)(nil)
+)
diff --git a/internal/tui/flamegraph/model.go b/internal/tui/flamegraph/model.go
index 68ce7fd..73285f9 100644
--- a/internal/tui/flamegraph/model.go
+++ b/internal/tui/flamegraph/model.go
@@ -113,6 +113,19 @@ type LiveTrieSource interface {
Configurator
}
+// --- compile-time interface satisfaction assertions ---
+//
+// *coreflamegraph.LiveTrie is the sole production implementation of all three
+// trie interfaces. The assertions are placed here rather than in the
+// flamegraph package itself to avoid an import cycle: runtime imports
+// flamegraph, so flamegraph cannot import runtime. The tui/flamegraph package
+// already imports coreflamegraph, making it the natural home.
+var (
+ _ Snapshotter = (*coreflamegraph.LiveTrie)(nil)
+ _ Configurator = (*coreflamegraph.LiveTrie)(nil)
+ _ LiveTrieSource = (*coreflamegraph.LiveTrie)(nil)
+)
+
type zoomState struct {
path string
previousSelectedIdx int
diff --git a/internal/tui/tui.go b/internal/tui/tui.go
index 6124fcd..eee4252 100644
--- a/internal/tui/tui.go
+++ b/internal/tui/tui.go
@@ -1247,6 +1247,23 @@ func placeToViewport(width, height int, content string) string {
return lipgloss.Place(width, height, lipgloss.Left, lipgloss.Top, content)
}
+// --- compile-time interface satisfaction assertions ---
+//
+// These blank-identifier assignments cause a build error if any concrete type
+// drifts out of sync with the interface it claims to satisfy.
+
+var (
+ // *runtimeBindings must satisfy the full TUI runtime contract, which
+ // composes RuntimePublisher (write side) and RuntimeState (read side).
+ _ runtime.TraceRuntimeBindings = (*runtimeBindings)(nil)
+
+ // lateBoundDashboardSource must satisfy the SnapshotSource contract used
+ // by the dashboard model. It wraps the injected stats engine and forwards
+ // calls through runtimeBindings so the dashboard source can be wired
+ // before the actual engine is available.
+ _ dashboardui.SnapshotSource = (*lateBoundDashboardSource)(nil)
+)
+
func altScreenView(content, title string) tea.View {
view := tea.NewView(content)
view.AltScreen = true