Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling Cases in repeated_async Jobs Where Execution Time Exceeds Interval Time #56

Open
DMCKirito opened this issue Nov 12, 2023 · 0 comments

Comments

@DMCKirito
Copy link

DMCKirito commented Nov 12, 2023

Hello,

I am currently working with a repeated_async type job in my project, where the job runs at an interval of 2 seconds. In most cases, it functions as expected. However, I've encountered a scenario where certain I/O operations, such as an unexpected MySQL connection timeout, cause a significant delay. This delay results in subsequent tasks being unable to execute.

Upon reviewing the source code, I noticed that the next_tick is always incremented based on the previous execution time (always moving from 11:05:31 -> 11:05:33 -> 11:05:35, for example), whereas the last_tick represents the time when the current task completes. This behavior seems to lead to a situation where, if a task takes longer than the job's interval, subsequent jobs are never executed.

let next_and_last_tick = match job {
      Ok(Some(job)) => {
          let job_type: JobType = JobType::from_i32(job.job_type).unwrap();
          let schedule = job.schedule();
          let repeated_every = job.repeated_every();
          let next_tick = job.next_tick_utc();
          let next_tick = match job_type {
              JobType::Cron => schedule.and_then(|s| s.after(&now).next()),
              JobType::OneShot => None,
              JobType::Repeated => repeated_every.and_then(|r| {
                  next_tick.and_then(|nt| {
                      nt.checked_add_signed(chrono::Duration::seconds(
                          r as i64,
                      ))
                  })
              }),
          };
          let last_tick = Some(now);
          Some((next_tick, last_tick))
      }
      _ => {
          error!("Could not get job metadata");
          None
      }

What I am looking for is a behavior more akin to a loop with a sleep mechanism, where, regardless of how long a job takes to execute, the next job would still run after the fixed interval. Is there any consideration for adding such a job type?

Thank you for your attention to this matter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant