diff --git a/CHANGELOG.md b/CHANGELOG.md index 84300eb..d60f831 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## madsim [0.2.26] - 2024-03-18 + +### Fixed + +- `sleep` and `sleep_until` now sleep for at least 1ms to be consistent with tokio's behavior. + ## rdkafka [0.3.3] - 2024-02-28 ### Changed diff --git a/madsim/Cargo.toml b/madsim/Cargo.toml index b3206a8..0037dee 100644 --- a/madsim/Cargo.toml +++ b/madsim/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "madsim" -version = "0.2.25" +version = "0.2.26" edition = "2021" authors = ["Runji Wang "] description = "Deterministic Simulator for distributed systems." @@ -62,7 +62,7 @@ tokio-util = { version = "0.7", features = ["codec"] } [dev-dependencies] criterion = "0.5" structopt = "0.3" -tokio = { version = "1", features = ["rt-multi-thread", "macros"] } +tokio = { version = "1", features = ["rt-multi-thread", "macros", "io-util"] } [[bench]] name = "rpc" diff --git a/madsim/src/sim/time/mod.rs b/madsim/src/sim/time/mod.rs index da371f2..1bfd847 100644 --- a/madsim/src/sim/time/mod.rs +++ b/madsim/src/sim/time/mod.rs @@ -106,15 +106,20 @@ impl TimeHandle { } /// Waits until `duration` has elapsed. + /// + /// It will sleep for at least 1ms to be consistent with the behavior of `tokio::time::sleep`. pub fn sleep(&self, duration: Duration) -> Sleep { self.sleep_until(self.clock.now_instant() + duration) } /// Waits until `deadline` is reached. + /// + /// It will sleep for at least 1ms to be consistent with the behavior of `tokio::time::sleep_until`. pub fn sleep_until(&self, deadline: Instant) -> Sleep { + let min_deadline = self.clock.now_instant() + Duration::from_millis(1); Sleep { handle: self.clone(), - deadline, + deadline: deadline.max(min_deadline), } } @@ -233,6 +238,15 @@ mod tests { fn time() { let runtime = Runtime::new(); runtime.block_on(async { + // sleep for at least 1ms + let t0 = Instant::now(); + sleep(Duration::default()).await; + assert!(t0.elapsed() >= Duration::from_millis(1)); + + let t0 = Instant::now(); + sleep_until(t0).await; + assert!(t0.elapsed() >= Duration::from_millis(1)); + let t0 = Instant::now(); sleep(Duration::from_secs(1)).await;