mvniekerk / tokio-cron-scheduler

Schedule tasks on Tokio using cron-like annotation
Apache License 2.0
529 stars 59 forks source link

Cannot remove jobs because adding does not return a UUID #19

Closed mmstick closed 2 years ago

mmstick commented 2 years ago

The documentation claims this is possible:

let job_id = sched.add(Job::new("1/10 * * * * *".parse().unwrap(), || {
    println!("I get executed every 10 seconds!");
}));
sched.remove(job_id);

But this is not possible because the return value is Ok(()).

mmstick commented 2 years ago

Couldn't get this scheduler to work at all in my application for some reason, so I came up with an alternative design. Are you open for PRs simplifying and improving the API? I was able to achieve this example in 180 lines of code with the only dependencies being chrono, cron, flume, and futures.

// Creates a scheduler based on the Local timezone. Note that the `sched_service`
// contains the background job as a future for the caller to decide how to await
// it. When the scheduler is dropped, the scheduler service will exit as well.
let (mut scheduler, sched_service) = Scheduler::<Local>::launch(smol::Timer::after);

// Creates a job which executes every 1 seconds.
let job = Job::cron("1/1 * * * * *").unwrap();
let fizz_id = scheduler.insert(job, |_id| println!("Fizz"));

// Creates a job which executes every 3 seconds.
let job = Job::cron("1/3 * * * * *").unwrap();
let buzz_id = scheduler.insert(job, |_id| println!("Buzz"));

// Creates a job which executes every 5 seconds.
let job = Job::cron("1/5 * * * * *").unwrap();
let bazz_id = scheduler.insert(job, |_id| println!("Bazz"));

// A future which gradually drops jobs from the scheduler.
let dropper = async move {
    Timer::after(Duration::from_secs(7)).await;
    scheduler.remove(fizz_id);
    println!("Fizz gone");
    Timer::after(Duration::from_secs(5)).await;
    scheduler.remove(buzz_id);
    println!("Buzz gone");
    Timer::after(Duration::from_secs(1)).await;
    scheduler.remove(bazz_id);
    println!("Bazz gone");

    // `scheduler` is dropped here, which causes the sched_service to end.
};

// Poll the dropper and scheduler service concurrently until both return.
futures::future::join(sched_service, dropper).await;

It's compatible with futures::executor::block_on, async_io::block_on, and tokio. Tokio support only requires passing tokio::time::sleep as the launch argument, and the sched_service can either be spawned or awaited directly.

mvniekerk commented 2 years ago

Hi @mmstick, thanks for the report. You're right, there was a breaking change somewhere. I have updated the documentation and also added the functionality back in 0.6.2.

As for the PR - yes I am definitely open to PRs. I am concerned though that given the current user facing API such a change suggested above is going to be a breaking change?