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