You've already forked agentic-coding-workflow
fix(jobs): timer leak in Module.Stop and warn on unknown runner names
Module.Stop used time.After which leaks the timer if the done channel
wins first; switch to time.NewTimer + defer Stop() to align with the
codebase convention.
scheduleEntry silently returned {0, false} for unknown runner names —
typos in production wiring were invisible. Return (entry, known) and
log Warn at NewModule registration time so misconfiguration surfaces.
This commit is contained in:
+14
-9
@@ -47,7 +47,10 @@ func NewModule(cfg Config, deps ModuleDeps) *Module {
|
||||
|
||||
sch := NewScheduler(log)
|
||||
for name, fn := range deps.RunnerFns {
|
||||
entry := scheduleEntry(cfg, name)
|
||||
entry, known := scheduleEntry(cfg, name)
|
||||
if !known {
|
||||
log.Warn("jobs.module.unknown_runner", "name", name)
|
||||
}
|
||||
sch.Add(name, entry.interval, entry.enabled, fn)
|
||||
}
|
||||
|
||||
@@ -95,10 +98,12 @@ func (m *Module) Stop(ctx context.Context) {
|
||||
if grace <= 0 {
|
||||
grace = 30 * time.Second
|
||||
}
|
||||
timer := time.NewTimer(grace)
|
||||
defer timer.Stop()
|
||||
select {
|
||||
case <-done:
|
||||
m.log.Info("jobs.module.stopped")
|
||||
case <-time.After(grace):
|
||||
case <-timer.C:
|
||||
m.log.Warn("jobs.module.shutdown_timeout", "grace_ms", grace.Milliseconds())
|
||||
case <-ctx.Done():
|
||||
m.log.Warn("jobs.module.shutdown_ctx_canceled")
|
||||
@@ -112,18 +117,18 @@ type schedEntry struct {
|
||||
enabled bool
|
||||
}
|
||||
|
||||
func scheduleEntry(cfg Config, name string) schedEntry {
|
||||
func scheduleEntry(cfg Config, name string) (schedEntry, bool) {
|
||||
switch name {
|
||||
case "workspace_fetch":
|
||||
return schedEntry{cfg.WorkspaceFetch.Interval, cfg.WorkspaceFetch.Enabled}
|
||||
return schedEntry{cfg.WorkspaceFetch.Interval, cfg.WorkspaceFetch.Enabled}, true
|
||||
case "worktree_prune":
|
||||
return schedEntry{cfg.WorktreePrune.Interval, cfg.WorktreePrune.Enabled}
|
||||
return schedEntry{cfg.WorktreePrune.Interval, cfg.WorktreePrune.Enabled}, true
|
||||
case "attachment_cleanup":
|
||||
return schedEntry{cfg.AttachmentCleanup.Interval, cfg.AttachmentCleanup.Enabled}
|
||||
return schedEntry{cfg.AttachmentCleanup.Interval, cfg.AttachmentCleanup.Enabled}, true
|
||||
case "job_reaper":
|
||||
return schedEntry{cfg.JobReaper.Interval, cfg.JobReaper.Enabled}
|
||||
return schedEntry{cfg.JobReaper.Interval, cfg.JobReaper.Enabled}, true
|
||||
case "job_purge":
|
||||
return schedEntry{cfg.JobPurge.Interval, cfg.JobPurge.Enabled}
|
||||
return schedEntry{cfg.JobPurge.Interval, cfg.JobPurge.Enabled}, true
|
||||
}
|
||||
return schedEntry{0, false}
|
||||
return schedEntry{0, false}, false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user