feat(jobs): persist job lifecycle to PostgreSQL job_audit

UpsertQueued/Running/MarkTerminal через SetPersistHooks; исправлен deadlock
fireEnqueued под Registry mutex.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Denozordec
2026-05-25 10:33:57 +07:00
co-authored by Cursor
parent 4a57c91e29
commit e65cf0d958
4 changed files with 106 additions and 15 deletions
+31 -9
View File
@@ -56,18 +56,40 @@ func BootstrapWorkers(ctx context.Context, opts Options) (store.Backend, *jobs.R
wk.Registry = reg
if pool != nil {
audit := repository.NewJobAuditWriter(pool)
reg.SetTerminalHook(func(j *jobs.Job) {
jobMeta := func(j *jobs.Job) map[string]any {
if j == nil {
return
return nil
}
st := j.Snapshot()
status, _ := st["status"].(string)
var errMsg *string
if e, ok := st["error"].(string); ok && e != "" {
errMsg = &e
}
audit.MarkTerminal(context.Background(), j.TenantID, j.ID, status, errMsg, time.Now().UTC())
})
meta, _ := st["meta"].(map[string]any)
return meta
}
reg.SetPersistHooks(
func(j *jobs.Job) {
if j == nil {
return
}
audit.UpsertQueued(context.Background(), j.TenantID, j.ID, j.Kind, j.IdempotencyKey, j.ModuleID, jobMeta(j))
},
func(j *jobs.Job) {
if j == nil {
return
}
audit.UpsertRunning(context.Background(), j.TenantID, j.ID, j.Kind, j.IdempotencyKey, jobMeta(j))
},
func(j *jobs.Job) {
if j == nil {
return
}
st := j.Snapshot()
status, _ := st["status"].(string)
var errMsg *string
if e, ok := st["error"].(string); ok && e != "" {
errMsg = &e
}
audit.MarkTerminal(context.Background(), j.TenantID, j.ID, status, errMsg, time.Now().UTC())
},
)
}
observability.RegisterStoreBackend(backend)
return backend, reg, pool, nil