pop-os / async-cron-scheduler

Runtime-agnostic async task scheduler with cron expression support
Mozilla Public License 2.0
5 stars 1 forks source link

blocks in actix-web until scheduler is dropped #1

Closed tyrsday29 closed 1 month ago

tyrsday29 commented 1 month ago

Hi!

So I was super excited to use your crate, but after testing briefly I realized that using this crate in actix-web seems to block the server from actually executing until the jobs are dropped from the scheduler. not sure if I'm doing something incorrectly based on the read me- just using the example. Any advice would be greatly appreciated!

mmstick commented 1 month ago

Sounds like you're not joining your future correctly. You'd have to share your code to see why it's blocking.

tyrsday29 commented 1 month ago

Thanks for getting back to me so quickly! Here's the code- am currently trying to join the futures down at the bottom with my http and https server currently, but am struggling a bit

[tokio::main]

async fn main() -> std::io::Result<()> {

smol::block_on(async move {
    // 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(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")).await;

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

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

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

///////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////// //http server with redirect to https let server = HttpServer::new(|| { ...

//https server let server2 = HttpServer::new(move || { ...

futures::try_join!(server, server2).map_err(|e| { eprintln!("Server error"); Error::new(ErrorKind::Other, "server error") })?;

Ok(())

}

mmstick commented 1 month ago

smol::block_on is your problem. You're already using tokio, so it's redundant to use smol inside of it. block_on blocks until the future returns.

mmstick commented 1 month ago

You should be adding your server's futures to the joined future set so that they're all being awaited concurrently.

tyrsday29 commented 1 month ago

thanks a bunch, got it working. Awesome crate btw!!