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:
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();