Skip to content

🚦 refactor(cmd): app lifecycle struct for runTUI β€” replace dual WaitGroups + comment-ordered defers; ctx-aware watcher.RunΒ #426

@martinciu

Description

@martinciu

πŸ” Problem

runTUI (cmd/ccpulse/main.go:258-384, ~127 lines) wires everything inline β€” env resolution, devlog, cache open/rebuild, pricing, auto-recost, ingester, watcher, quota seam, TUI model β€” and then manages goroutine lifecycle by hand:

  • Two separate sync.WaitGroups (bg, bfDone), two cancel funcs
  • A five-deep defer stack whose relative order is load-bearing and documented only in a 16-line block comment (main.go:322-337)
  • Adding any new background worker requires re-deriving the ordering contract from prose; shutdown_test.go exists precisely because this is fragile

Related watcher shape: pkg/watcher/watcher.go:56-81 β€” Run takes no context.Context (shutdown is solely via Close() closing fsnotify channels), and fsnotify errors are silently dropped (watcher.go:74-79). The watcher callback closes over the root ctx for ProcessFile, but the watcher itself can't be cancelled by that ctx.

The current design is correct (per #52's shutdown-discipline work) β€” this is a maintainability refactor, not a bug fix.

πŸ› οΈ Suggested shape

  • An app struct holding the wired deps with start(ctx) / shutdown() methods, so registration order and teardown order live in code (a slice of stop funcs or errgroup) rather than in a comment
  • errgroup.WithContext per lifecycle stage (backfill group + long-running group), waited in one deterministic teardown
  • Add ctx to watcher.Run (select on ctx.Done()), giving the fsnotify error stream a propagation path; keep w.Close() as the post-p.Run() trigger

⚠️ Notes

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestgoPull requests that update go codeimportance: lowPolish, refactor, or nice-to-havesize: mMedium β€” 1 to 3 hours

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions