modify clock to use simulated time instead

This commit is contained in:
pedrocarlo
2025-07-10 11:32:01 -03:00
parent d72a7f5d8e
commit 4a13286d62
5 changed files with 66 additions and 12 deletions

View File

@@ -4,6 +4,17 @@ pub struct Instant {
pub micros: u32,
}
impl<T: chrono::TimeZone> From<chrono::DateTime<T>> for Instant {
fn from(value: chrono::DateTime<T>) -> Self {
Instant {
secs: value.timestamp(),
micros: value.timestamp_subsec_micros(),
}
}
}
pub trait Clock {
fn now(&self) -> Instant;
}

34
simulator/runner/clock.rs Normal file
View File

@@ -0,0 +1,34 @@
use std::cell::RefCell;
use chrono::{DateTime, Utc};
use rand::Rng;
use rand_chacha::ChaCha8Rng;
#[derive(Debug)]
pub struct SimulatorClock {
curr_time: RefCell<DateTime<Utc>>,
rng: RefCell<ChaCha8Rng>,
}
impl SimulatorClock {
const MIN_TICK: u64 = 1;
const MAX_TICK: u64 = 50;
pub fn new(rng: ChaCha8Rng) -> Self {
Self {
curr_time: RefCell::new(Utc::now()),
rng: RefCell::new(rng),
}
}
pub fn now(&self) -> DateTime<Utc> {
let mut time = self.curr_time.borrow_mut();
let nanos = self
.rng
.borrow_mut()
.gen_range(Self::MIN_TICK..Self::MAX_TICK);
let nanos = std::time::Duration::from_micros(nanos);
*time = *time + nanos;
*time
}
}

View File

@@ -4,12 +4,13 @@ use std::{
sync::Arc,
};
use chrono::{DateTime, Utc};
use rand::Rng as _;
use rand_chacha::ChaCha8Rng;
use tracing::{instrument, Level};
use turso_core::{File, Result};
use crate::model::FAULT_ERROR_MSG;
use crate::{model::FAULT_ERROR_MSG, runner::clock::SimulatorClock};
pub(crate) struct SimulatorFile {
pub(crate) inner: Arc<dyn File>,
pub(crate) fault: Cell<bool>,
@@ -40,12 +41,13 @@ pub(crate) struct SimulatorFile {
pub sync_completion: RefCell<Option<Arc<turso_core::Completion>>>,
pub queued_io: RefCell<Vec<DelayedIo>>,
pub clock: Arc<SimulatorClock>,
}
type IoOperation = Box<dyn FnOnce(&SimulatorFile) -> Result<Arc<turso_core::Completion>>>;
pub struct DelayedIo {
pub time: std::time::Instant,
pub time: turso_core::Instant,
pub op: IoOperation,
}
@@ -95,17 +97,19 @@ impl SimulatorFile {
}
#[instrument(skip_all, level = Level::TRACE)]
fn generate_latency_duration(&self) -> Option<std::time::Instant> {
fn generate_latency_duration(&self) -> Option<turso_core::Instant> {
let mut rng = self.rng.borrow_mut();
// Chance to introduce some latency
rng.gen_bool(self.latency_probability as f64 / 100.0)
.then(|| {
std::time::Instant::now() + std::time::Duration::from_millis(rng.gen_range(5..15))
let now: DateTime<Utc> = self.clock.now().into();
let sum = now + std::time::Duration::from_millis(rng.gen_range(5..20));
sum.into()
})
}
#[instrument(skip_all, level = Level::DEBUG)]
pub fn run_queued_io(&self, now: std::time::Instant) -> Result<()> {
pub fn run_queued_io(&self, now: turso_core::Instant) -> Result<()> {
let mut queued_io = self.queued_io.borrow_mut();
// TODO: as we are not in version 1.87 we cannot use `extract_if`
// so we have to do something different to achieve the same thing

View File

@@ -7,7 +7,10 @@ use rand::{RngCore, SeedableRng};
use rand_chacha::ChaCha8Rng;
use turso_core::{Clock, Instant, MemoryIO, OpenFlags, PlatformIO, Result, IO};
use crate::{model::FAULT_ERROR_MSG, runner::file::SimulatorFile};
use crate::{
model::FAULT_ERROR_MSG,
runner::{clock::SimulatorClock, file::SimulatorFile},
};
pub(crate) struct SimulatorIO {
pub(crate) inner: Box<dyn IO>,
@@ -18,6 +21,7 @@ pub(crate) struct SimulatorIO {
pub(crate) page_size: usize,
seed: u64,
latency_probability: usize,
clock: Arc<SimulatorClock>,
}
unsafe impl Send for SimulatorIO {}
@@ -30,6 +34,8 @@ impl SimulatorIO {
let files = RefCell::new(Vec::new());
let rng = RefCell::new(ChaCha8Rng::seed_from_u64(seed));
let nr_run_once_faults = Cell::new(0);
let clock = SimulatorClock::new(ChaCha8Rng::seed_from_u64(seed));
Ok(Self {
inner,
fault,
@@ -39,6 +45,7 @@ impl SimulatorIO {
page_size,
seed,
latency_probability,
clock: Arc::new(clock),
})
}
@@ -59,11 +66,7 @@ impl SimulatorIO {
impl Clock for SimulatorIO {
fn now(&self) -> Instant {
let now = chrono::Local::now();
Instant {
secs: now.timestamp(),
micros: now.timestamp_subsec_micros(),
}
self.clock.now().into()
}
}
@@ -89,6 +92,7 @@ impl IO for SimulatorIO {
latency_probability: self.latency_probability,
sync_completion: RefCell::new(None),
queued_io: RefCell::new(Vec::new()),
clock: self.clock.clone(),
});
self.files.borrow_mut().push(file.clone());
Ok(file)
@@ -109,7 +113,7 @@ impl IO for SimulatorIO {
FAULT_ERROR_MSG.into(),
));
}
let now = std::time::Instant::now();
let now = self.now();
for file in self.files.borrow().iter() {
file.run_queued_io(now)?;
}

View File

@@ -1,5 +1,6 @@
pub mod bugbase;
pub mod cli;
pub mod clock;
pub mod differential;
pub mod doublecheck;
pub mod env;