diff --git a/internal/scheduler/task.go b/internal/scheduler/task.go index 50b3f9c..6d98ebf 100644 --- a/internal/scheduler/task.go +++ b/internal/scheduler/task.go @@ -3,36 +3,33 @@ package scheduler import ( "context" "cycle-scheduler/internal/job" - "sync" "sync/atomic" "time" ) -// safeTime wraps a `time.Timer` with a lock to be thread safe. -type safeTimer struct { - l sync.Mutex - timer *time.Timer +// atomicTimer wraps a `time.Timer`. +type atomicTimer struct { + atomic.Pointer[time.Timer] } -func (st *safeTimer) stop() { - if st.timer != nil { - st.timer.Stop() +func (at *atomicTimer) stop() { + timer := at.Load() + if timer != nil { + timer.Stop() } } // set replaces the current timer. // It also ensures that the current timer is stopped. -func (st *safeTimer) set(t *time.Timer) { - st.l.Lock() - defer st.l.Unlock() - - if st.timer != nil { - st.timer.Stop() - st.timer = t +func (at *atomicTimer) set(t *time.Timer) { + timer := at.Load() + if timer != nil { + timer.Stop() + at.Swap(t) return } - st.timer = t + at.Swap(t) } type TaskDetails struct { @@ -43,23 +40,21 @@ type TaskDetails struct { type task struct { *job.Job attempts atomic.Uint32 - timer *safeTimer + timer atomicTimer } func newTask(f job.FnJob) *task { j := job.NewJob(f) t := task{ Job: &j, - timer: &safeTimer{}, + timer: atomicTimer{}, } return &t } func (t *task) abort() { - if t.timer != nil { - t.timer.stop() - } + t.timer.stop() t.Job.Abort() }