mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-07 13:51:36 +00:00
I-003: job timeout reaper closes AwaitingCSR/AwaitingApproval gap
Add 11th always-on scheduler loop that transitions jobs stuck in
AwaitingCSR (default 24h TTL) or AwaitingApproval (default 168h TTL)
to Failed. I-001's retry loop then auto-promotes eligible Failed jobs
back to Pending. No new status enum, no schema migration.
- JobRepository.ListTimedOutAwaitingJobs with per-status cutoff WHERE
- JobService.ReapTimedOutJobs mirrors RetryFailedJobs structure
- Scheduler jobTimeoutLoop with atomic.Bool idempotency guard, 2m
per-tick context, WaitGroup shutdown drain
- Config: CERTCTL_JOB_TIMEOUT_INTERVAL (10m), CERTCTL_JOB_AWAITING_CSR_TIMEOUT
(24h), CERTCTL_JOB_AWAITING_APPROVAL_TIMEOUT (168h)
- Audit event per transition: actor=system, actorType=System,
action=job_timeout, details={old_status, new_status, timeout_reason,
age_hours}
- 14 new tests: 3 config, 7 service, 4 scheduler
This commit is contained in:
@@ -742,6 +742,25 @@ func (m *mockJobRepository) ClaimPendingByAgentID(ctx context.Context, agentID s
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ListTimedOutAwaitingJobs is the I-003 integration-mock stub. Returns jobs whose
|
||||
// created_at predates the relevant cutoff for their status.
|
||||
func (m *mockJobRepository) ListTimedOutAwaitingJobs(ctx context.Context, csrCutoff, approvalCutoff time.Time) ([]*domain.Job, error) {
|
||||
var jobs []*domain.Job
|
||||
for _, j := range m.jobs {
|
||||
switch j.Status {
|
||||
case domain.JobStatusAwaitingCSR:
|
||||
if j.CreatedAt.Before(csrCutoff) {
|
||||
jobs = append(jobs, j)
|
||||
}
|
||||
case domain.JobStatusAwaitingApproval:
|
||||
if j.CreatedAt.Before(approvalCutoff) {
|
||||
jobs = append(jobs, j)
|
||||
}
|
||||
}
|
||||
}
|
||||
return jobs, nil
|
||||
}
|
||||
|
||||
type mockAuditRepository struct {
|
||||
events []*domain.AuditEvent
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user