fix(app): respect cfg.Jobs.ShutdownGrace and skip jobs.Stop when disabled

Code review fixes for T16:
- Pass cfg.Jobs.ShutdownGrace+5s to jobs.Stop call-site context (was
  hard-coded 30s, would mask configured longer grace).
- Guard jobs.Stop block on cfg.Jobs.Enabled so disabled jobs don't
  spin up the no-op shutdown goroutine + timer.
- Use clock.Real().Now() in deadLetterFn for consistency with the rest
  of the jobs wiring.
This commit is contained in:
2026-05-06 11:10:29 +08:00
parent c7db7a9604
commit 69c5831783
+5 -5
View File
@@ -311,7 +311,7 @@ func New(ctx context.Context, cfg *config.Config, dist embed.FS) (*App, error) {
"job_id": job.ID.String(), "job_id": job.ID.String(),
"job_type": string(job.Type), "job_type": string(job.Type),
}, },
CreatedAt: time.Now().UTC(), CreatedAt: clock.Real().Now().UTC(),
}); derr != nil { }); derr != nil {
log.Warn("dead_letter.dispatch_failed", "admin_id", a.ID, "err", derr.Error()) log.Warn("dead_letter.dispatch_failed", "admin_id", a.ID, "err", derr.Error())
} }
@@ -412,9 +412,9 @@ func (a *App) Run(ctx context.Context) error {
} }
// Stop jobs module first so no in-flight worker can dispatch new // Stop jobs module first so no in-flight worker can dispatch new
// notifications after we begin to drain the dispatcher. // notifications after we begin to drain the dispatcher.
if a.jobs != nil { if a.jobs != nil && a.cfg.Jobs.Enabled {
a.jobsCancel() a.jobsCancel()
stopCtx, stopCancel := context.WithTimeout(context.Background(), 30*time.Second) stopCtx, stopCancel := context.WithTimeout(context.Background(), a.cfg.Jobs.ShutdownGrace+5*time.Second)
a.jobs.Stop(stopCtx) a.jobs.Stop(stopCtx)
stopCancel() stopCancel()
} }
@@ -427,9 +427,9 @@ func (a *App) Run(ctx context.Context) error {
case err := <-errCh: case err := <-errCh:
drainCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second) drainCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel() defer cancel()
if a.jobs != nil { if a.jobs != nil && a.cfg.Jobs.Enabled {
a.jobsCancel() a.jobsCancel()
stopCtx, stopCancel := context.WithTimeout(context.Background(), 30*time.Second) stopCtx, stopCancel := context.WithTimeout(context.Background(), a.cfg.Jobs.ShutdownGrace+5*time.Second)
a.jobs.Stop(stopCtx) a.jobs.Stop(stopCtx)
stopCancel() stopCancel()
} }