Description
Scheduler has no Drop implementation. When the only Scheduler handle goes out of scope, the inner Arc<RwLock> is still referenced by every spawned task via the tasks clone captured at spawn time. All
tasks continue running indefinitely, holding memory, CPU, and JoinHandle resources until the process exits.
Affected file
- src/scheduler/mod.rs — Scheduler struct (no Drop impl)
Reproduction
{
let mut scheduler = Scheduler::build();
scheduler.schedule(Box::new(task), every(1.seconds())).unwrap();
} // scheduler dropped here — tasks keep running
Impact
- Infinite tasks run forever after the scheduler is dropped.
- In tests or short-lived scopes, this leaks threads/Tokio tasks for the lifetime of the process.
- Users have no way to do a "stop everything" shutdown without manually calling abort() on every ID first.
Fix
Implement Drop for Scheduler to abort all live tasks:
impl Drop for Scheduler {
fn drop(&mut self) {
let ids: Vec<_> = self.read().unwrap().keys().copied().collect();
for id in ids {
// abort handle and remove
if let Some(task) = self.write().unwrap().remove(&id) {
*task.status.write().unwrap() = TaskStatus::Abort;
task.handle.abort(); // async; use condvar signal for sync
}
}
}
}
Description
Scheduler has no Drop implementation. When the only Scheduler handle goes out of scope, the inner Arc<RwLock> is still referenced by every spawned task via the tasks clone captured at spawn time. All
tasks continue running indefinitely, holding memory, CPU, and JoinHandle resources until the process exits.
Affected file
Reproduction
Impact
Fix
Implement Drop for Scheduler to abort all live tasks: