fix: preserve the ordering of read/write operations on atomic variables

This commit is contained in:
Saber Haj Rabiee
2025-03-28 13:55:18 -07:00
parent 94acdc24c7
commit 2ea0381bb5
19 changed files with 103 additions and 92 deletions

View File

@@ -829,7 +829,7 @@ mod tests {
println!("next run");
}
println!("{:?}", *store.user().read());
combined_count.fetch_add(1, Ordering::Relaxed);
combined_count.fetch_add(1, Ordering::SeqCst);
}
});
tick().await;
@@ -841,7 +841,7 @@ mod tests {
store.user().update(|name| name.push_str("!!!"));
tick().await;
// the effect reads from `user`, so it should trigger every time
assert_eq!(combined_count.load(Ordering::Relaxed), 4);
assert_eq!(combined_count.load(Ordering::SeqCst), 4);
}
#[tokio::test]
@@ -861,7 +861,7 @@ mod tests {
println!("next run");
}
println!("{:?}", *store.todos().read());
combined_count.fetch_add(1, Ordering::Relaxed);
combined_count.fetch_add(1, Ordering::SeqCst);
}
});
tick().await;
@@ -873,7 +873,7 @@ mod tests {
store.user().update(|name| name.push_str("!!!"));
tick().await;
// the effect reads from `todos`, so it shouldn't trigger every time
assert_eq!(combined_count.load(Ordering::Relaxed), 1);
assert_eq!(combined_count.load(Ordering::SeqCst), 1);
}
#[tokio::test]
@@ -893,7 +893,7 @@ mod tests {
println!("next run");
}
println!("{:?}", *store.todos().read());
combined_count.fetch_add(1, Ordering::Relaxed);
combined_count.fetch_add(1, Ordering::SeqCst);
}
});
tick().await;
@@ -902,7 +902,7 @@ mod tests {
tick().await;
store.set(data());
tick().await;
assert_eq!(combined_count.load(Ordering::Relaxed), 3);
assert_eq!(combined_count.load(Ordering::SeqCst), 3);
}
#[tokio::test]
@@ -922,7 +922,7 @@ mod tests {
println!("next run");
}
println!("{:?}", *store.read());
combined_count.fetch_add(1, Ordering::Relaxed);
combined_count.fetch_add(1, Ordering::SeqCst);
}
});
tick().await;
@@ -935,7 +935,7 @@ mod tests {
tick().await;
store.todos().write().clear();
tick().await;
assert_eq!(combined_count.load(Ordering::Relaxed), 5);
assert_eq!(combined_count.load(Ordering::SeqCst), 5);
}
#[tokio::test]
@@ -958,7 +958,7 @@ mod tests {
"{:?}",
store.todos().iter_unkeyed().collect::<Vec<_>>()
);
combined_count.store(1, Ordering::Relaxed);
combined_count.store(1, Ordering::SeqCst);
}
});
@@ -972,7 +972,7 @@ mod tests {
tick().await;
store.todos().write().push(Todo::new("Profit!"));
// the effect only reads from `todos`, so it should trigger only the first time
assert_eq!(combined_count.load(Ordering::Relaxed), 1);
assert_eq!(combined_count.load(Ordering::SeqCst), 1);
}
#[tokio::test]
@@ -995,7 +995,7 @@ mod tests {
println!("next run");
}
println!("{:?}", *store.todos().read());
combined_count.fetch_add(1, Ordering::Relaxed);
combined_count.fetch_add(1, Ordering::SeqCst);
}
});
tick().await;
@@ -1010,7 +1010,7 @@ mod tests {
todos: vec![],
});
tick().await;
assert_eq!(combined_count.load(Ordering::Relaxed), 1);
assert_eq!(combined_count.load(Ordering::SeqCst), 1);
store.patch(Todos {
user: "Carol".into(),
@@ -1020,7 +1020,7 @@ mod tests {
}],
});
tick().await;
assert_eq!(combined_count.load(Ordering::Relaxed), 2);
assert_eq!(combined_count.load(Ordering::SeqCst), 2);
}
#[tokio::test]
@@ -1056,7 +1056,7 @@ mod tests {
println!("next run");
}
println!("{:?}", *store.user().read());
combined_count.fetch_add(1, Ordering::Relaxed);
combined_count.fetch_add(1, Ordering::SeqCst);
}
});
tick().await;
@@ -1066,13 +1066,13 @@ mod tests {
todos: vec![],
});
tick().await;
assert_eq!(combined_count.load(Ordering::Relaxed), 2);
assert_eq!(combined_count.load(Ordering::SeqCst), 2);
store.patch(CustomTodos {
user: "Carol".into(),
todos: vec![],
});
tick().await;
assert_eq!(combined_count.load(Ordering::Relaxed), 3);
assert_eq!(combined_count.load(Ordering::SeqCst), 3);
store.patch(CustomTodos {
user: "Carol".into(),
@@ -1082,7 +1082,7 @@ mod tests {
}],
});
tick().await;
assert_eq!(combined_count.load(Ordering::Relaxed), 3);
assert_eq!(combined_count.load(Ordering::SeqCst), 3);
}
#[derive(Debug, Store)]

View File

@@ -137,7 +137,7 @@ mod tests {
println!("no inner value");
}
combined_count.fetch_add(1, Ordering::Relaxed);
combined_count.fetch_add(1, Ordering::SeqCst);
}
});
@@ -161,7 +161,7 @@ mod tests {
.unwrap()
.push_str("!!!");
tick().await;
assert_eq!(combined_count.load(Ordering::Relaxed), 5);
assert_eq!(combined_count.load(Ordering::SeqCst), 5);
assert_eq!(
store
.name()
@@ -196,7 +196,7 @@ mod tests {
}
println!(" is_some = {}", store.name().read().is_some());
parent_count.fetch_add(1, Ordering::Relaxed);
parent_count.fetch_add(1, Ordering::SeqCst);
}
});
Effect::new_sync({
@@ -216,20 +216,20 @@ mod tests {
.unwrap_or_default()
.len())
);
inner_count.fetch_add(1, Ordering::Relaxed);
inner_count.fetch_add(1, Ordering::SeqCst);
}
});
tick().await;
assert_eq!(parent_count.load(Ordering::Relaxed), 1);
assert_eq!(inner_count.load(Ordering::Relaxed), 1);
assert_eq!(parent_count.load(Ordering::SeqCst), 1);
assert_eq!(inner_count.load(Ordering::SeqCst), 1);
store.name().set(Some(Name {
first_name: Some("Greg".into()),
}));
tick().await;
assert_eq!(parent_count.load(Ordering::Relaxed), 2);
assert_eq!(inner_count.load(Ordering::Relaxed), 2);
assert_eq!(parent_count.load(Ordering::SeqCst), 2);
assert_eq!(inner_count.load(Ordering::SeqCst), 2);
println!("\nUpdating first name only");
store
@@ -242,8 +242,8 @@ mod tests {
.push_str("!!!");
tick().await;
assert_eq!(parent_count.load(Ordering::Relaxed), 3);
assert_eq!(inner_count.load(Ordering::Relaxed), 3);
assert_eq!(parent_count.load(Ordering::SeqCst), 3);
assert_eq!(inner_count.load(Ordering::SeqCst), 3);
}
#[tokio::test]
@@ -284,7 +284,7 @@ mod tests {
}
println!(" value = {:?}", store.inner().get());
parent_count.fetch_add(1, Ordering::Relaxed);
parent_count.fetch_add(1, Ordering::SeqCst);
}
});
Effect::new_sync({
@@ -309,7 +309,7 @@ mod tests {
" value = {:?}",
store.inner().map_untracked(|inner| inner.first().get())
);
inner_first_count.fetch_add(1, Ordering::Relaxed);
inner_first_count.fetch_add(1, Ordering::SeqCst);
}
});
Effect::new_sync({
@@ -325,14 +325,14 @@ mod tests {
" value = {:?}",
store.inner().map(|inner| inner.second().get())
);
inner_second_count.fetch_add(1, Ordering::Relaxed);
inner_second_count.fetch_add(1, Ordering::SeqCst);
}
});
tick().await;
assert_eq!(parent_count.load(Ordering::Relaxed), 1);
assert_eq!(inner_first_count.load(Ordering::Relaxed), 1);
assert_eq!(inner_second_count.load(Ordering::Relaxed), 1);
assert_eq!(parent_count.load(Ordering::SeqCst), 1);
assert_eq!(inner_first_count.load(Ordering::SeqCst), 1);
assert_eq!(inner_second_count.load(Ordering::SeqCst), 1);
println!("\npatching with A/C");
store.patch(Outer {
@@ -346,7 +346,6 @@ mod tests {
assert_eq!(parent_count.load(Ordering::Relaxed), 2);
assert_eq!(inner_first_count.load(Ordering::Relaxed), 1);
assert_eq!(inner_second_count.load(Ordering::Relaxed), 2);
store.patch(Outer { inner: None });
tick().await;