I am having some problems with timers: I cannot identify the reason why this is not working properly:
use std::sync::{Arc, Mutex};
use timer::Timer;
struct Counter {
value: i32,
}
impl Counter {
fn new() -> Self {
Self { value: 0 }
}
fn increment(&mut self) {
self.value += 1;
}
fn get_value(&self) -> i32 {
self.value
}
}
#[test]
fn test_1() {
let counter = Arc::new(Mutex::new(Counter::new()));
let counter_clone_1 = Arc::clone(&counter);
let counter_clone_2 = Arc::clone(&counter_clone_1);
// Arrange
let callback = {
move || {
println!("Callback executed");
counter_clone_1.lock().unwrap().increment();
}
};
let timer = Timer::new();
println!("Timer created");
timer.schedule_with_delay(chrono::Duration::seconds(2), callback);
// Assert initial value
println!("Initial assert");
assert_eq!(counter_clone_2.lock().unwrap().get_value(), 0);
// Act
println!("Sleeping for 4 seconds");
std::thread::sleep(std::time::Duration::new(4, 0));
// Assert incremented value
println!("Final assert");
assert_eq!(counter.lock().unwrap().get_value(), 1);
}
Why is the callback not being called after the specified timeout?
I tried with multiple timeouts (including zero) without success and this is the outcome I see:
Timer created
Initial assert
Sleeping for 4 seconds
Final assert
thread 'missed_ping_timer_tests::test_1' panicked at tests\missed_ping_timer_tests.rs:51:5:
assertion `left == right` failed
left: 0
right: 1
This is what I have in my Cargo.toml
file:
[dependencies]
timer = "0.2.0"
chrono = "0.4.39"
If you read the documentation of schedule_with_delay
you'll find it says:
This method returns a
Guard
object. If thatGuard
is dropped, execution is cancelled.
Since you don't assign the guard object to any variable it is immediately dropped and execution of the callback is cancelled.
You can simply assign it to a binding to not drop and cancel it immediately:
let _guard = timer.schedule_with_delay(chrono::Duration::seconds(2), callback);
The leading underscore suppresses the warning that the variable is not used