Merge 'Improve Simulator IO by handing RowResult::IO' from Arpit Saxena

This is not related to any open issue (atleast from the ones I saw).
This is related to an issue I saw when running the simulator as it was
calling `io.run_once()` even before submitting any read/write job. This
would lead to it hanging since io_uring's submit_and_wait would keep
waiting for a completion event.
I've tried to improve the simulator's IO handling a bit:
We inject a fault before calling next_row() through which we'll get
pread faults. Also we call io's run_once on getting RowResult::IO. This
is run with a fault probability of 1%. This is less because a fault here
would result us in terminating the entire loop iterating on rows, and
also because realistically we'll expect less faults here.
PS: I think run_once() should not hang either when no operation is
pending in io_uring. Opened #349 for fixing that.

Closes #348
This commit is contained in:
Pekka Enberg
2024-09-26 14:13:49 -07:00

View File

@@ -19,15 +19,10 @@ fn main() {
Err(_) => todo!(),
};
for _ in 0..100 {
io.inject_fault(rng.gen_bool(0.5));
match io.run_once() {
Ok(_) => {}
Err(_) => continue,
}
let conn = db.connect();
let mut stmt = conn.prepare("SELECT * FROM users").unwrap();
let mut rows = stmt.query().unwrap();
loop {
'rows_loop: loop {
io.inject_fault(rng.gen_bool(0.5));
match rows.next_row() {
Ok(result) => {
@@ -36,7 +31,10 @@ fn main() {
// TODO: assert that data is correct
}
limbo_core::RowResult::IO => {
todo!();
io.inject_fault(rng.gen_bool(0.01));
if io.run_once().is_err() {
break 'rows_loop;
}
}
limbo_core::RowResult::Done => {
break;
@@ -58,6 +56,7 @@ struct SimulatorIO {
fault: RefCell<bool>,
files: RefCell<Vec<Rc<SimulatorFile>>>,
rng: RefCell<ChaCha8Rng>,
nr_run_once_faults: RefCell<usize>,
}
impl SimulatorIO {
@@ -66,11 +65,13 @@ impl SimulatorIO {
let fault = RefCell::new(false);
let files = RefCell::new(Vec::new());
let rng = RefCell::new(ChaCha8Rng::seed_from_u64(seed));
let nr_run_once_faults = RefCell::new(0);
Ok(Self {
inner,
fault,
files,
rng,
nr_run_once_faults,
})
}
@@ -82,6 +83,7 @@ impl SimulatorIO {
}
fn print_fault_stats(&self) {
println!("run_once faults: {}", self.nr_run_once_faults.borrow());
for file in self.files.borrow().iter() {
file.print_fault_stats();
}
@@ -103,6 +105,7 @@ impl IO for SimulatorIO {
fn run_once(&self) -> Result<()> {
if *self.fault.borrow() {
*self.nr_run_once_faults.borrow_mut() += 1;
return Err(limbo_core::LimboError::InternalError(
"Injected fault".into(),
));