fix(simulation): address #843 review — seeding, atomics, API consistency
Review fixes from Hoshe + Tyre: - EntityRng seeding: splitmix64(seed) ^ splitmix64(id) instead of splitmix64(seed + id) — eliminates collision class where adjacent seeds produce identical streams - AtomicBool ordering: Relaxed → SeqCst for shutdown flag (correct on weakly-ordered architectures) - Worker Drop: join handles instead of detaching threads - Normalize stub API: remove ChunkGenWorker convenience wrappers, use .pool consistently across all 3 workers - trigger_monologue: downgrade &mut to shared refs (no-op anchor was blocking parallel systems) - Remove dead SimRng inserts from migrated monologue tests - Document determinism gap on poll_worker_results - Document bevy_tasks/rayon dep rationale in Cargo.toml Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -54,7 +54,7 @@ pub struct BackgroundWorkerPool<Req, Resp> {
|
||||
tx: Sender<WorkRequest<Req>>,
|
||||
rx: Receiver<(Resp, DeliveryStrategy)>,
|
||||
shutdown: Arc<AtomicBool>,
|
||||
_workers: Vec<JoinHandle<()>>,
|
||||
workers: Vec<JoinHandle<()>>,
|
||||
}
|
||||
|
||||
impl<Req, Resp> BackgroundWorkerPool<Req, Resp>
|
||||
@@ -84,7 +84,7 @@ where
|
||||
let handle = thread::Builder::new()
|
||||
.name(format!("worker-{id}"))
|
||||
.spawn(move || {
|
||||
while !shutdown.load(Ordering::Relaxed) {
|
||||
while !shutdown.load(Ordering::SeqCst) {
|
||||
match rx.recv_timeout(std::time::Duration::from_millis(100)) {
|
||||
Ok(work) => {
|
||||
let strategy = work.strategy;
|
||||
@@ -107,7 +107,7 @@ where
|
||||
tx: req_tx,
|
||||
rx: resp_rx,
|
||||
shutdown,
|
||||
_workers: workers,
|
||||
workers,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,13 +146,16 @@ where
|
||||
|
||||
/// Signal all workers to shut down gracefully.
|
||||
pub fn shutdown(&self) {
|
||||
self.shutdown.store(true, Ordering::Relaxed);
|
||||
self.shutdown.store(true, Ordering::SeqCst);
|
||||
}
|
||||
}
|
||||
|
||||
impl<Req, Resp> Drop for BackgroundWorkerPool<Req, Resp> {
|
||||
fn drop(&mut self) {
|
||||
self.shutdown.store(true, Ordering::Relaxed);
|
||||
// Workers will exit on next recv_timeout cycle (100ms max)
|
||||
self.shutdown.store(true, Ordering::SeqCst);
|
||||
// Join all worker threads — wait for clean exit (100ms max per thread)
|
||||
for handle in self.workers.drain(..) {
|
||||
let _ = handle.join();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user