mvniekerk / tokio-cron-scheduler

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

JobDeleter::remove gets stuck when called from tokio::spawn #40

Closed skrcka closed 1 year ago

skrcka commented 1 year ago

JobDeleter::remove works fine when called from tokio::main but if I call it in a new thread (tokio::spawn) it gets stuck.

It gets stuck on the first JobDeleter::remove tokio::spawn

Tokio just doesn't want to spawn a new thread or is somehow blocked. I am running everything in multi_thread environment.

I managed to fix it by removing one tokio::spawn and making the function async

pub async fn remove(context: &Context, job_id: &Uuid) -> Result<(), JobSchedulerError> {
        let delete = context.job_delete_tx.clone();
        let mut deleted = context.job_deleted_tx.subscribe();
        let (tx, rx) = std::sync::mpsc::channel();

        let job_id = *job_id;
        tokio::spawn(async move {
            if let Err(e) = delete.send(job_id) {
                error!("Error sending delete id {:?}", e);
            }
        });
        while let Ok(deleted) = deleted.recv().await {
            let ret = match deleted {
                Ok(uuid) => {
                    if uuid == job_id {
                        Ok(())
                    } else {
                        continue;
                    }
                }
                Err((e, Some(uuid))) => {
                    if uuid == job_id {
                        Err(e)
                    } else {
                        continue;
                    }
                }
                _ => continue,
            };
            if let Err(e) = tx.send(ret) {
                error!("Error sending removal result {:?}", e);
            }
            else {
                break;
            }
        }

        let ret = rx.recv();
        match ret {
            Ok(ret) => ret,
            Err(e) => {
                error!("Error receiving result from job deletion {:?}", e);
                Err(JobSchedulerError::CantRemove)
            }
        }
    }

Note: this isn't a proper fix, is hacky and isn't properly tested but it works in my case

mvniekerk commented 1 year ago

Hi @skrcka Thank you for the report. Lots of these little bugs are due to me trying to mix async with sync. I'll have a look on the above what you've suggested, and report back here.

mvniekerk commented 1 year ago

v0.9.2 released, have a look.

skrcka commented 1 year ago

Thanks @mvniekerk v0.9.3 did the trick