diff options
| -rw-r--r-- | internal/ior.go | 6 | ||||
| -rw-r--r-- | internal/ior_bpfsetup.go | 4 | ||||
| -rw-r--r-- | internal/tui/tui.go | 34 |
3 files changed, 36 insertions, 8 deletions
diff --git a/internal/ior.go b/internal/ior.go index 4bd5c8a..ab52299 100644 --- a/internal/ior.go +++ b/internal/ior.go @@ -108,7 +108,8 @@ func validateRunConfig(cfg flags.Config) error { func tuiTestFlamesStarter(cfg flags.Config) tui.TraceStarter { return func(ctx context.Context) error { engine, streamBuf, liveTrie := buildTestFlamesRuntime(cfg) - if bindings, ok := tui.RuntimeBindingsFromContext(ctx); ok { + // Only setter methods are needed here; use the narrower publisher interface. + if bindings, ok := tui.RuntimePublisherFromContext(ctx); ok { bindings.SetDashboardSnapshotSource(engine) bindings.SetEventStreamSource(streamBuf) bindings.SetLiveTrie(liveTrie) @@ -120,7 +121,8 @@ func tuiTestFlamesStarter(cfg flags.Config) tui.TraceStarter { func tuiTestLiveFlamesStarter(cfg flags.Config) tui.TraceStarter { return func(ctx context.Context) error { engine, streamBuf, liveTrie := buildTestLiveFlamesRuntime(ctx, cfg) - if bindings, ok := tui.RuntimeBindingsFromContext(ctx); ok { + // Only setter methods are needed here; use the narrower publisher interface. + if bindings, ok := tui.RuntimePublisherFromContext(ctx); ok { bindings.SetDashboardSnapshotSource(engine) bindings.SetEventStreamSource(streamBuf) bindings.SetLiveTrie(liveTrie) diff --git a/internal/ior_bpfsetup.go b/internal/ior_bpfsetup.go index cf0b112..3500106 100644 --- a/internal/ior_bpfsetup.go +++ b/internal/ior_bpfsetup.go @@ -70,7 +70,9 @@ func setupBPFModule(parentCtx context.Context, cfg flags.Config) (*bpf.Module, * bpfModule.Close() return nil, nil, releaseBindings, setupBPFModuleError("attach probes", err) } - if bindings, ok := tui.RuntimeBindingsFromContext(parentCtx); ok { + // setupBPFModule only injects the probe manager; it does not read TUI state, + // so RuntimePublisher is the correct narrower interface to use here. + if bindings, ok := tui.RuntimePublisherFromContext(parentCtx); ok { bindings.SetProbeManager(mgr) releaseBindings = func() { bindings.SetProbeManager(nil) } } diff --git a/internal/tui/tui.go b/internal/tui/tui.go index 432fc14..252e722 100644 --- a/internal/tui/tui.go +++ b/internal/tui/tui.go @@ -58,19 +58,31 @@ type ProbeManager interface { ActiveCount() (int, int) } -// TraceRuntimeBindings allows a trace starter to publish runtime dependencies -// (snapshot source, stream source, probe manager) into the active TUI model. -type TraceRuntimeBindings interface { +// RuntimePublisher is the write side of the TUI runtime contract. +// A trace starter calls these methods to inject live data into the active TUI. +type RuntimePublisher interface { SetDashboardSnapshotSource(source SnapshotSource) SetEventStreamSource(source eventstream.Source) SetLiveTrie(liveTrie flamegraphtui.LiveTrieSource) SetProbeManager(manager ProbeManager) +} + +// RuntimeState is the read side of the TUI runtime contract. +// A trace starter calls these methods to obtain persistent state owned by the TUI. +type RuntimeState interface { StreamBuffer() eventstream.Source Recorder() *parquet.Recorder StreamSequencer() *eventstream.Sequencer FilterEpoch() uint64 } +// TraceRuntimeBindings composes RuntimePublisher and RuntimeState so a trace +// starter can both inject live data and read persistent TUI-owned state. +type TraceRuntimeBindings interface { + RuntimePublisher + RuntimeState +} + type runtimeBindingsContextKey struct{} type traceFiltersContextKey struct{} @@ -200,8 +212,9 @@ func (r *runtimeBindings) resetDashboardSnapshotSource() *statsengine.Snapshot { return nil } -// RuntimeBindingsFromContext returns model-scoped trace bindings when the -// context was created by the TUI. +// RuntimeBindingsFromContext returns the full TraceRuntimeBindings when the +// context was created by the TUI. Use RuntimePublisherFromContext when only +// write access is needed. func RuntimeBindingsFromContext(ctx context.Context) (TraceRuntimeBindings, bool) { bindings, ok := ctx.Value(runtimeBindingsContextKey{}).(TraceRuntimeBindings) if !ok || bindings == nil { @@ -210,6 +223,17 @@ func RuntimeBindingsFromContext(ctx context.Context) (TraceRuntimeBindings, bool return bindings, true } +// RuntimePublisherFromContext returns only the RuntimePublisher side of the +// TUI bindings. Use this when the caller only injects data and does not need +// to read persistent TUI state. +func RuntimePublisherFromContext(ctx context.Context) (RuntimePublisher, bool) { + bindings, ok := ctx.Value(runtimeBindingsContextKey{}).(RuntimePublisher) + if !ok || bindings == nil { + return nil, false + } + return bindings, true +} + // ContextWithRuntimeBindings stores trace runtime bindings on the context. func ContextWithRuntimeBindings(ctx context.Context, bindings TraceRuntimeBindings) context.Context { return context.WithValue(ctx, runtimeBindingsContextKey{}, bindings) |
