Commit f2bdef57 authored by ale's avatar ale

Fix the StateManager to track individual WithStatus invocations

Prevents a panic when nesting WithStatus calls (for whatever reason).
parent e6853790
......@@ -4,6 +4,7 @@ import (
"container/list"
"context"
"errors"
"fmt"
"sync"
"time"
......@@ -160,7 +161,7 @@ func (j *exclusiveJob) RunContext(ctx context.Context) error {
if cur, ok := j.mgr.locked[key]; ok {
if !j.killAndRun {
// TODO: return nil?
return errors.New("skipped (overrun)")
return fmt.Errorf("job %s skipped (overrun)", j.ID())
}
cur.Cancel()
cur.Wait() // nolint
......@@ -267,6 +268,10 @@ type Status struct {
//
// It has no practical effect on the jobs themselves, it's just a way
// to provide the user with debugging and auditing information.
//
// Note that it must use its own random ID, and not job.ID, otherwise
// nesting WithStatus handlers on the same job will cause panics (due
// to duplicated transitions from state to state).
type StateManager struct {
mx sync.Mutex
pending map[string]*Status
......@@ -286,12 +291,12 @@ func NewStateManager() *StateManager {
}
}
func (m *StateManager) setStatusPending(name string, j Job) {
func (m *StateManager) setStatusPending(id, name string, j Job) {
m.mx.Lock()
defer m.mx.Unlock()
m.pending[j.ID()] = &Status{
ID: j.ID(),
m.pending[id] = &Status{
ID: id,
Name: name,
Status: JobStatusPending,
Job: j,
......@@ -331,8 +336,9 @@ func (m *StateManager) WithStatus(j Job, name string) Job {
sj := &statusJob{
Job: j,
mgr: m,
id: util.RandomID(),
}
m.setStatusPending(name, sj)
m.setStatusPending(sj.id, name, sj)
return sj
}
......@@ -366,12 +372,13 @@ func (m *StateManager) GetStatus() ([]Status, []Status, []Status) {
type statusJob struct {
Job
mgr *StateManager
id string
}
func (j *statusJob) RunContext(ctx context.Context) error {
j.mgr.setStatusRunning(j.ID())
j.mgr.setStatusRunning(j.id)
err := j.Job.RunContext(ctx)
j.mgr.setStatusDone(j.ID(), err)
j.mgr.setStatusDone(j.id, err)
return err
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment