Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Using same value in multiple "new_repeated_async" jobs in tokio_cron_scheduler

Here is a simplified version of the problem the problem that I’m having:

use std::time::Duration;
use tokio_cron_scheduler::{JobScheduler, Job};

#[derive(Clone, Debug)]
struct Obj {
    a: String,
    b: u64,
}

#[tokio::main]
async fn main() {

    let obj = Obj {
        a: "A".to_string(),
        b: 64,
    };

    let sched = JobScheduler::new().await.unwrap();

    let job = Job::new_repeated_async(Duration::from_secs(2), |_, _| Box::pin(async move {
        foo(&obj);
    })).unwrap();
    sched.add(job).await.unwrap();

    let job = Job::new_repeated_async(Duration::from_secs(5), |_, _| Box::pin(async move {
        bar(&obj);
    })).unwrap();
    sched.add(job).await.unwrap();

    sched.start().await.unwrap();

    tokio::time::sleep(core::time::Duration::from_secs(100)).await;
}


fn foo(o: &Obj) {
    println!("{}", o.a);
}

fn bar(o: &Obj) {
    println!("{}", o.b);
}

But this doesn’t work because I get the error "cannot move out of obj, a captured variable in an FnMut closure.

My initial thought was that I just had to wrap "obj" in an Arc and clone it before creating the job:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

let obj = Arc::new(Obj {
    a: "A".to_string(),
    b: 64,
});
...
let o = obj.clone();
let job = Job::new_repeated_async(Duration::from_secs(2), |_, _| Box::pin(async move {
    foo(&o);
})).unwrap();
...

but this doesn’t work either and I get the same error.

I then just tried to clone obj without the Arc before passing it to the job, and again the same error.

I found similar error messages on the site but none of them seemed to be able to help me solve this one. Can anyone help?

>Solution :

You didn’t clone in the right places. You need to clone for each async move future returned, and for the first closure too:

let job = Job::new_repeated_async(Duration::from_secs(2), {
    let obj = Arc::clone(&obj);
    move |_, _| {
        let obj = Arc::clone(&obj);
        Box::pin(async move {
            foo(&obj);
        })
    }
})
.unwrap();
sched.add(job).await.unwrap();

let job = Job::new_repeated_async(Duration::from_secs(5), move |_, _| {
    let obj = Arc::clone(&obj);
    Box::pin(async move {
        bar(&obj);
    })
})
.unwrap();
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading