Skip to content

Commit 0dda31d

Browse files
committed
Drop real-time sleep from MockMicrogridApiClient::new()
`new()` slept up to ~1 s of wall-clock time aligning to the next whole second so the mock's telemetry timestamps would land on the resampler's interval boundaries. The anchor is now built directly from `next_sec_secs` and handed to `TokioSyncedClock::with_wall_anchor`, so the boundary is reported at construction without waiting for real time to reach it. The sleep was incidentally syncing the mock's clock with a later `TokioSyncedClock::new()` (anchored to `Utc::now()`) that `new_logical_meter_handle` was passing to `LogicalMeterHandle`; expose the mock's clock via a new `clock()` accessor and share it with the actor so the two sides remain aligned without depending on real wall time. Signed-off-by: Sahas Subramanian <sahas.subramanian@proton.me>
1 parent 0a2aa96 commit 0dda31d

2 files changed

Lines changed: 16 additions & 13 deletions

File tree

src/client/test_utils.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -251,28 +251,30 @@ impl MockComponent {
251251

252252
impl MockMicrogridApiClient {
253253
/// Creates a new `MockMicrogridApiClient` with an internally-owned
254-
/// [`TokioSyncedClock`]. Sleeps until the start of the next second
255-
/// before anchoring the clock so that telemetry timestamps line up with
256-
/// the resampler's interval boundaries, giving reproducible resampled
257-
/// values in tests.
254+
/// [`TokioSyncedClock`] anchored to the next whole-second boundary, so
255+
/// telemetry timestamps line up with the resampler's interval boundaries
256+
/// and tests get reproducible resampled values.
258257
pub fn new(graph: MockComponent) -> Self {
259-
let now = SystemTime::now();
260-
let since_epoch = now
258+
let since_epoch = SystemTime::now()
261259
.duration_since(SystemTime::UNIX_EPOCH)
262260
.unwrap_or_default();
263261
let next_sec_secs = since_epoch.as_secs() + 1;
264-
let next_sec = SystemTime::UNIX_EPOCH + std::time::Duration::from_secs(next_sec_secs);
265-
std::thread::sleep(next_sec.duration_since(now).unwrap_or_default());
266262

267-
// Anchor the clock to `next_sec` exactly (not `Utc::now()` post-sleep,
268-
// which would overshoot by tens of µs and cause samples emitted at
269-
// nominal interval boundaries to land just past the resampler
270-
// window's right edge).
263+
// The anchor is the wall-clock value `TokioSyncedClock` will report
264+
// at the current tokio instant; it doesn't have to match real time,
265+
// so there's no need to sleep until the boundary actually arrives.
271266
let anchor = chrono::DateTime::<chrono::Utc>::from_timestamp(next_sec_secs as i64, 0)
272267
.unwrap_or_else(chrono::Utc::now);
273268
Self::new_with_clock(graph, TokioSyncedClock::with_wall_anchor(anchor))
274269
}
275270

271+
/// Returns a clone of the clock driving telemetry timestamps. Pass it
272+
/// to [`LogicalMeterHandle::try_new_with_clock`] so the resampler and
273+
/// the mock observe the same wall-clock value at every tokio instant.
274+
pub fn clock(&self) -> TokioSyncedClock {
275+
self.clock.clone()
276+
}
277+
276278
/// Creates a `MockMicrogridApiClient` whose telemetry timestamps come
277279
/// from the given clock. Share a clone with [`LogicalMeterActor`] to
278280
/// simulate whole-machine NTP jumps that both sides observe.

src/logical_meter/logical_meter_handle.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,10 +241,11 @@ mod tests {
241241
]),
242242
);
243243

244+
let clock = api_client.clock();
244245
LogicalMeterHandle::try_new_with_clock(
245246
MicrogridClientHandle::new_from_client(api_client),
246247
config.unwrap_or_else(|| LogicalMeterConfig::new(TimeDelta::try_seconds(1).unwrap())),
247-
crate::client::test_utils::TokioSyncedClock::new(),
248+
clock,
248249
)
249250
.await
250251
.unwrap()

0 commit comments

Comments
 (0)