This commit is contained in:
2026-06-20 19:16:44 +08:00
parent db3d030169
commit dbb87823e8
26 changed files with 676 additions and 115 deletions
+21 -6
View File
@@ -54,15 +54,17 @@ func NewModule(cfg Config, deps ModuleDeps) *Module {
sch.Add(name, entry.interval, entry.enabled, fn)
}
handlerTimeout := handlerTimeoutFor(cfg.JobReaper)
workers := make([]*Worker, cfg.Workers)
for i := 0; i < cfg.Workers; i++ {
workers[i] = NewWorker(deps.Repo, deps.Handlers, WorkerOptions{
ID: workerID(i),
PollInterval: 200 * time.Millisecond,
Backoff: deps.WorkerBackoff,
Clock: clk,
Log: log,
OnDeadLetter: deps.OnDeadLetter,
ID: workerID(i),
PollInterval: 200 * time.Millisecond,
Backoff: deps.WorkerBackoff,
Clock: clk,
Log: log,
HandlerTimeout: handlerTimeout,
OnDeadLetter: deps.OnDeadLetter,
})
}
return &Module{cfg: cfg, scheduler: sch, workers: workers, log: log}
@@ -112,6 +114,19 @@ func (m *Module) Stop(ctx context.Context) {
func workerID(i int) string { return "worker#" + strconv.Itoa(i) }
// handlerTimeoutFor derives the per-job handler timeout from the reaper's lease
// timeout, leaving a margin below it so a healthy long handler finishes (or is
// canceled) before the reaper re-leases the job and double-runs it. Returns 0
// (no timeout) when reaping is disabled or no positive lease timeout is set.
func handlerTimeoutFor(rc JobReaperConfig) time.Duration {
if !rc.Enabled || rc.LeaseTimeout <= 0 {
return 0
}
// 90% of the lease window leaves headroom for the write-back to land before
// the reaper's cutoff.
return rc.LeaseTimeout - rc.LeaseTimeout/10
}
type schedEntry struct {
interval time.Duration
enabled bool