diff --git a/job.go b/job.go index 2a54fc32..f831d944 100644 --- a/job.go +++ b/job.go @@ -31,6 +31,7 @@ type Job struct { type runConfig struct { finiteRuns bool maxRuns int + removeAfterLastRun bool } // NewJob creates a new Job with the provided interval @@ -147,3 +148,10 @@ func (j *Job) RunCount() int { runCount := j.runCount return runCount } +// RemoveAfterLastRun update the job in order to remove the job after its last exec +func (j *Job)RemoveAfterLastRun() *Job { + j.Lock() + defer j.Unlock() + j.runConfig.removeAfterLastRun = true + return j +} diff --git a/scheduler.go b/scheduler.go index 638f9df5..aefede3c 100644 --- a/scheduler.go +++ b/scheduler.go @@ -456,6 +456,12 @@ func (s *Scheduler) StartImmediately() *Scheduler { // shouldRun returns true if the Job should be run now func (s *Scheduler) shouldRun(j *Job) bool { + + // option remove the job's in the scheduler after its last execution + if j.runConfig.removeAfterLastRun && (j.runConfig.maxRuns - j.runCount) == 1 { + s.RemoveByReference(j) + } + return j.shouldRun() && s.time.Now(s.loc).Unix() >= j.nextRun.Unix() } diff --git a/scheduler_test.go b/scheduler_test.go index d112a481..3c330d8c 100644 --- a/scheduler_test.go +++ b/scheduler_test.go @@ -881,3 +881,18 @@ func TestDo(t *testing.T) { }) } } + +func TestRemoveAfterExec(t *testing.T) { + s := NewScheduler(time.UTC) + s.StartAsync() + + job, err := s.Every(1).StartAt(time.Now().Add(1*time.Second)).Do(task, s) + require.NoError(t, err) + + job.LimitRunsTo(1) + job.RemoveAfterLastRun() + + time.Sleep(2 * time.Second) + + assert.Zero(t, len(s.Jobs())) +}