mvniekerk / tokio-cron-scheduler

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

I was wondering how can I pass any variabel that did not implement Copy trait; #72

Closed rockburning closed 2 months ago

rockburning commented 2 months ago

source code

#[derive(Clone,)]
pub struct TaskTest{
    id: String
}

#[async_trait::async_trait]
impl PodProcessor for TaskTest{
    async fn process(&mut  self, id: &str)->anyhow::Result<()> {
        println!("hell  {}",id.to_string());
        Ok(())
    }
}

#[tokio::main]
async fn main() -> Result<(), JobSchedulerError> {
    let mut sched = JobScheduler::new().await?;

    // Add basic cron job
   let s = "32".to_string() ;
    let s_clone = s.clone();
    let mut handle = TaskTest {
        id: "".to_string(),
    };

    // let processor = Arc::new(handle) as Arc<dyn PodProcessor>;
    // let proc_clone = processor.clone();
    // let handle = proc_clone.clone().process(Arc::new(s));
    sched.add(
        Job::new_async("1/7 * * * * *", move |uuid, mut l| {
            Box::pin(async move {
                handle.process("123").await;
            })
        })?
    ).await?;

    // Start the scheduler
    sched.start().await?;

    // Wait while the jobs run
    tokio::time::sleep(Duration::from_secs(100)).await;

    Ok(())
}

ERRO is

296 Job::new_async("1/7 *", move uuid, mut l { ------------------ captured by this FnMut closure 297 Box::pin(async move { __^ 298 handle.process("123").await;
variable moved due to use in coroutine
move occurs because handle has type TaskTest, which does not implement the Copy trait
299 })
_____^ handle is moved here
rockburning commented 2 months ago

as shown in the above; my struct TaskTest has its own attribute id is string which is common type in strcut; when I want to capture it in the clousure it show the error above;

mvniekerk commented 2 months ago

Hi @rockburning Thank you for the reporting the issue.

We're using Tokio, this uses "task stealing" in terms of how it does async sheduling. That means, a task can move between threads. For Tokio, the struct being passed on should be implementing Copy. Some other async schedulers doesn't use task stealing, which removes the need of Copy.

That means, in practice, that you'll need to either resort to .clones() or to things that use Arc<RwLock<_>> in order to sync sending these structs over threads.

Sorry, this is Rust's fearless concurrency hitting you with this issue.

mvniekerk commented 2 months ago

For references: https://users.rust-lang.org/t/help-with-tokio-rwlock-and-the-copy-trait/48486 https://users.rust-lang.org/t/how-to-pass-struct-to-other-function-that-use-tokio-without-copy-trait/103775/6

Yeah there's plenty of people hitting the same issue.

Feel free to re-open this issue if you think we should handle this differently?