diff options
| author | Paul Buetow <paul@buetow.org> | 2026-05-13 20:04:48 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-05-13 20:04:48 +0300 |
| commit | 251894cf3375812564ecf28392179b395cdda9c7 (patch) | |
| tree | 83c3609ab591702e29a375923670e7622a33b5c7 /internal/ior_profiling.go | |
| parent | 78ea9e22e596255c5e23ce445d80641870674ca9 (diff) | |
refactor: break down functions exceeding 50 lines into smaller helpers
Split 22 production files across the codebase — event loop, TUI models,
probe manager, dashboard, export, flag parsing, code generation, and
ioworkload scenarios — so that no function body exceeds 50 lines. Each
extracted helper carries its own comment explaining its role.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'internal/ior_profiling.go')
| -rw-r--r-- | internal/ior_profiling.go | 81 |
1 files changed, 49 insertions, 32 deletions
diff --git a/internal/ior_profiling.go b/internal/ior_profiling.go index ddae088..77790b9 100644 --- a/internal/ior_profiling.go +++ b/internal/ior_profiling.go @@ -37,50 +37,21 @@ func setupProfiling(ctx context.Context, cfg flags.Config, started chan<- struct } control.enabled = true - isTUIMode := started != nil - cpuProfilePath, memProfilePath, execTracePath, execTraceDuration := profilingFilesForMode(isTUIMode) + cpuProfilePath, memProfilePath, execTracePath, execTraceDuration := profilingFilesForMode(started != nil) - cpuProfile, err := os.Create(cpuProfilePath) + cpuProfile, memProfile, err := openProfilingFiles(cpuProfilePath, memProfilePath) if err != nil { return nil, err } - memProfile, err := os.Create(memProfilePath) - if err != nil { - _ = cpuProfile.Close() - return nil, err - } control.cpuProfile = cpuProfile control.memProfile = memProfile if execTracePath != "" { - execTraceProfile, err := os.Create(execTracePath) - if err != nil { + if err := startExecTrace(ctx, execTracePath, execTraceDuration, control); err != nil { _ = cpuProfile.Close() _ = memProfile.Close() return nil, err } - if err := trace.Start(execTraceProfile); err != nil { - _ = cpuProfile.Close() - _ = memProfile.Close() - _ = execTraceProfile.Close() - return nil, err - } - var stopOnce sync.Once - control.stopExecTrace = func() { - stopOnce.Do(func() { - trace.Stop() - _ = execTraceProfile.Close() - }) - } - go func() { - timer := time.NewTimer(execTraceDuration) - defer timer.Stop() - select { - case <-ctx.Done(): - case <-timer.C: - } - control.stopExecTrace() - }() } if err := pprof.StartCPUProfile(cpuProfile); err != nil { @@ -92,6 +63,52 @@ func setupProfiling(ctx context.Context, cfg flags.Config, started chan<- struct return control, nil } +// openProfilingFiles creates the CPU and memory profile output files. On +// error any successfully opened file is closed before returning. +func openProfilingFiles(cpuPath, memPath string) (*os.File, *os.File, error) { + cpuProfile, err := os.Create(cpuPath) + if err != nil { + return nil, nil, err + } + memProfile, err := os.Create(memPath) + if err != nil { + _ = cpuProfile.Close() + return nil, nil, err + } + return cpuProfile, memProfile, nil +} + +// startExecTrace creates the execution-trace output file, starts the runtime +// tracer, and wires a goroutine that stops it on context cancellation or after +// execTraceDuration, whichever comes first. +func startExecTrace(ctx context.Context, tracePath string, execTraceDuration time.Duration, control *profilingControl) error { + execTraceProfile, err := os.Create(tracePath) + if err != nil { + return err + } + if err := trace.Start(execTraceProfile); err != nil { + _ = execTraceProfile.Close() + return err + } + var stopOnce sync.Once + control.stopExecTrace = func() { + stopOnce.Do(func() { + trace.Stop() + _ = execTraceProfile.Close() + }) + } + go func() { + timer := time.NewTimer(execTraceDuration) + defer timer.Stop() + select { + case <-ctx.Done(): + case <-timer.C: + } + control.stopExecTrace() + }() + return nil +} + func (p *profilingControl) stop(logln func(...any)) { p.stopOnce.Do(func() { if !p.enabled { |
