fix(app): wire signal-aware context through controller startup#1787
fix(app): wire signal-aware context through controller startup#1787SarthakB11 wants to merge 1 commit intokagent-dev:mainfrom
Conversation
the controller's Start function used context.Background() for tracing init, migrations, and db connect, while ctrl.SetupSignalHandler() was only invoked later for mgr.Start. on sigterm during startup, those early operations ignored the cancellation and could hang past the pod's terminationGracePeriod. call ctrl.SetupSignalHandler() once at the top of Start, reuse the returned context for both startup work and mgr.Start. controller-runtime's signal handler must be called exactly once per process; collapsing the two call sites also removes a latent panic risk if a future caller added another signal-handler setup. resolves the long-standing 'TODO setup signal handlers' in app.go. Signed-off-by: SarthakB11 <sarthak.bhardwaj21b@iiitg.ac.in>
There was a problem hiding this comment.
Pull request overview
This PR ensures the controller’s startup path uses the same signal-aware context as mgr.Start, so SIGTERM during early initialization (tracing init, migrations, DB connect, etc.) can propagate cancellation and avoid hanging past Kubernetes termination grace periods. It also eliminates a second ctrl.SetupSignalHandler() call to align with controller-runtime’s “call once per process” requirement.
Changes:
- Initialize a single signal-aware
ctxviactrl.SetupSignalHandler()at the top ofapp.Start. - Reuse that
ctxthroughout startup and pass it intomgr.Startinstead of creating a second signal handler.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Reused below for mgr.Start; SetupSignalHandler must be called once per process. | ||
| ctx := ctrl.SetupSignalHandler() |
There was a problem hiding this comment.
good catch. you're right, the default runner at app.go:462 takes _ context.Context and migrations.RunUp doesn't accept ctx at all, so migrations aren't cancellable by this PR.
I have updated the description, this PR only makes tracing init, db connect, and the manager signal-aware, plus removes the duplicate ctrl.SetupSignalHandler() call. threading ctx through migrations.RunUp is a separate change. happy to open a follow-up if maintainers want it.
summary
app.Startconstructed two independent signal-handling setups: an earlyctx := context.Background()used for tracing init and db connect, and a separatectrl.SetupSignalHandler()passed tomgr.Startlater. controller-runtime requires the signal handler be set up exactly once per process, so the second call is a latent panic risk if a future caller adds another signal-handler setup. addresses the long-standing// TODO setup signal handlersatgo/core/pkg/app/app.go:297.ctrl.SetupSignalHandler()once at the top ofStartand reuse the returned context for both startup work andmgr.Start. tracing init, db connect, and the manager now share a single signal-aware ctx; the duplicate setup is gone.app.go:462) discards its ctx argument andmigrations.RunUpdoes not accept ctx, so migrations themselves are still not cancellable by this PR. threading ctx throughmigrations.RunUpis a separate change; happy to follow up.ai model disclosure
used claude code (claude opus 4.7) to triage and draft the diff. self-reviewed
go/core/pkg/app/app.goto confirm the secondctrl.SetupSignalHandler()call site at line 670 and the manager's downstream use ofctx. verified locally via: