mvniekerk / tokio-cron-scheduler

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

future created by async block is not `Sync` #15

Closed sheldonth closed 2 years ago

sheldonth commented 2 years ago

Give an async function called task the following code seems like it should work:

#[tokio::main]
async fn main() {
    //job().await 

    let mut sched = JobScheduler::new();

    let pin = Box::pin(async {
        task().await;
    });

    let job = Job::new_async("0 30 9-16 * * Mon,Tue,Wed,Thu,Fri",
                    |uuid, l| pin).unwrap();

    sched.add(job);
}

Yet I see the error

error: generator cannot be shared between threads safely
   --> src/main.rs:105:21
    |
105 | /                     Box::pin(async move {
106 | |                         job().await;
107 | |                     })
    | |______________________^ future created by async block is not `Sync`
    |
    = help: the trait `Sync` is not implemented for `dyn Future<Output = Result<Type, deadpool_postgres::tokio_postgres::Error>> + Send`
    = note: required for the cast to the object type `dyn Future<Output = ()> + Send + Sync`

error: generator cannot be shared between threads safely
   --> src/main.rs:105:21
    |
105 | /                     Box::pin(async move {
106 | |                         job().await;
107 | |                     })
    | |______________________^ future created by async block is not `Sync`
    |
    = help: the trait `Sync` is not implemented for `dyn Future<Output = Result<Statement, deadpool_postgres::tokio_postgres::Error>> + Send`
    = note: required for the cast to the object type `dyn Future<Output = ()> + Send + Sync`

Can't seem to find the error in my ways here. Appreciate any help.

sp1ff commented 2 years ago

Yes I'm hitting exactly the same problem.

annder commented 2 years ago

+1, I also encountering the same problem.

mvniekerk commented 2 years ago

Hi @sheldonth, @sp1ff, @annder Thanks for the bug reports.

So - root cause. The future you're trying to await on can't be sent between threads (there's no Sync trait implemented on the value). This is to do with the API you're trying to put inside of the async parts. That is unfortunately out of the scope of this crate. It was encountered with other people earlier https://github.com/mvniekerk/tokio-cron-scheduler/issues/8 so have look. Basically - their suggestion is to have an MPSC Sender that's moved to the scheduler job, and a receiver that runs in current thread / another thread that waits for values from the MSPC.