Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] - OneTime jobs should have the option to be deleted on completion #709

Open
rigens opened this issue Apr 16, 2024 · 3 comments
Open
Labels
enhancement New feature or request

Comments

@rigens
Copy link

rigens commented Apr 16, 2024

Describe the bug

...

To Reproduce

func main() {
	scheduler, err := gocron.NewScheduler(gocron.WithLocation(time.UTC))
	if err != nil {
		log.Fatal(err)
	}

	total := 100

	var wg sync.WaitGroup
	wg.Add(total)

	for i := 0; i < total; i++ {
		runAt := time.Now().UTC().Add(5 * time.Second)
		_, err := scheduler.NewJob(
			gocron.OneTimeJob(gocron.OneTimeJobStartDateTime(runAt)),
			gocron.NewTask(func() {
				log.Printf("running job at %s", time.Now().UTC())
				wg.Done()
			}),
		)
		if err != nil {
			log.Fatal(err)
		}
	}

	scheduler.Start()
	wg.Wait()

	log.Printf("total jobs: %d", len(scheduler.Jobs()))
}

Version

v2.2.9

Expected behavior

scheduler.Jobs() should return an empty slice after completing all OneTime jobs

Additional context

@rigens rigens added the bug Something isn't working label Apr 16, 2024
@JohnRoesler
Copy link
Contributor

I don't consider this a bug. Currently, you can run a one time job, and then if you choose to, can run it manually using RunNow().

I think this could be changed to a feature request to optionally remove the job when done.

@rigens
Copy link
Author

rigens commented May 10, 2024

Currently, you can run a one time job, and then if you choose to, can run it manually using RunNow()

Why would I use RunNow() if I can call the corresponding function directly

I don't consider this a bug.

This is a bug, OneTime jobs should be removed from the scheduler after execution (see quartz or apscheduler for example)

@JohnRoesler JohnRoesler changed the title [BUG] - OneTime jobs are not deleted after completion [FEATURE] - OneTime jobs should have the option to be deleted on completion May 24, 2024
@JohnRoesler JohnRoesler added enhancement New feature or request and removed bug Something isn't working labels May 24, 2024
@Zhwt
Copy link

Zhwt commented Feb 5, 2025

For anyone who comes later: you may want to use gocron.WithLimitedRuns(1) to make the job deleting itself upon completion. Example for the code above:

_, err := scheduler.NewJob(
	gocron.OneTimeJob(gocron.OneTimeJobStartDateTime(runAt)),
	gocron.NewTask(func() {
		log.Printf("running job at %s", time.Now().UTC())
		wg.Done()
	}),
	gocron.WithLimitedRuns(1),
)

But please note that there seems to be some subtle difference between the job being fired by the scheduler and directly called using job.RunNow(). The job seems to be counted as "done and removed" in fired job, and will be counted as "not started yet" or "done and removed" state when calling RunNow(). Reproduce code:

package main

import (
	"fmt"
	"github.com/go-co-op/gocron/v2"
	"time"
)

var s gocron.Scheduler

func remainingJobCount() {
	// remove this delay to see the difference
	time.Sleep(time.Microsecond * 10)
	fmt.Println("there are", len(s.Jobs()), "jobs in the queue")
}

func main() {
	var err error
	s, err = gocron.NewScheduler()
	if err != nil {
		fmt.Println(err)
	}
	s.Start()

	j, err := s.NewJob(
		gocron.OneTimeJob(gocron.OneTimeJobStartDateTime(time.Now().Add(time.Second))),
		gocron.NewTask(remainingJobCount),
		gocron.WithLimitedRuns(2),
	)
	if err != nil {
		fmt.Println(err)
	}

	time.Sleep(time.Second * 2)

	err = j.RunNow()
	if err != nil {
		fmt.Println(err)
	}

	time.Sleep(time.Second)

	remainingJobCount()
}

Will result in:

there are 1 jobs in the queue
there are 1 jobs in the queue
there are 0 jobs in the queue

or

there are 1 jobs in the queue
there are 0 jobs in the queue
there are 0 jobs in the queue

But the first one will always be 1. I'm not sure if this is the desired behavior, so I'm not posting this as a issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants