Skip to content

Bug: reschedule() does not take effect until after the current sleep completes #23

Description

@ZialeHub

Description

reschedule() atomically writes a new Recurrence into the Arc<RwLock>. However, the scheduler loop reads the interval before calling sleep, and tokio::time::sleep / std::thread::sleep is not
cancellable from outside once started. The new interval is therefore silently ignored for the remainder of the current sleep and only takes effect on the next iteration.

Affected files

  • src/scheduler/async_scheduler.rs — lines 90–95
  • src/scheduler/sync_scheduler.rs — lines 90–95

Reproduction

  let id = scheduler.schedule(Box::new(task), every(3600.seconds())).unwrap();
  // 1 second later:
  scheduler.reschedule(id, every(1.seconds())).unwrap();
  // Task does not run for another ~3599 seconds — reschedule had no immediate effect

Impact

Users calling reschedule() reasonably expect the new interval to take effect promptly. This is especially confusing when shortening a long interval.

Fix

Async: Replace tokio::time::sleep with a tokio::sync::Notify or tokio::time::interval + reset so the sleep can be interrupted:

  // Use a Notify stored alongside the task
  notify.notify_one(); // called inside reschedule()

  // In the loop:
  tokio::select! {
      _ = tokio::time::sleep(duration) => {}
      _ = notify.notified() => {}
  }

Sync: Use the same Condvar introduced for abort() interrupt (see issue).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions