fn run_concurrent_generation<T, F>(
num_threads: usize,
_ids_per_thread: usize,
generator_fn: F,
) -> Vec<Vec<T>>
where
T: Send + 'static,
F: Fn(usize) -> Vec<T> + Send + Sync + Clone + 'static,
{
use std::thread;
let handles: Vec<_> = (0..num_threads)
.map(|thread_idx| {
let generator = generator_fn.clone();
thread::spawn(move || generator(thread_idx))
})
.collect();
handles
.into_iter()
.map(|h| h.join().expect("Thread panicked"))
.collect()
}
fn assert_all_unique<T: Ord + Clone + std::fmt::Debug>(ids: &[T], context: &str) {
let mut sorted = ids.to_vec();
sorted.sort();
let original_len = sorted.len();
sorted.dedup();
assert_eq!(
original_len,
sorted.len(),
"{}: Found {} duplicate IDs out of {}",
context,
original_len - sorted.len(),
original_len
);
}
fn assert_global_uniqueness<T: Ord + Clone + std::fmt::Debug>(
thread_results: Vec<Vec<T>>,
context: &str,
) {
let mut all_ids: Vec<T> = thread_results.into_iter().flatten().collect();
let total = all_ids.len();
all_ids.sort();
all_ids.dedup();
assert_eq!(
total,
all_ids.len(),
"{}: Found {} duplicate IDs across threads (total {})",
context,
total - all_ids.len(),
total
);
}
fn assert_components_match<T>(
ids: &[T],
expected_worker: u64,
expected_process: u64,
components_fn: impl Fn(&T) -> (u64, u64),
) {
for id in ids {
let (worker_id, process_id) = components_fn(id);
assert_eq!(worker_id, expected_worker, "Worker ID mismatch");
assert_eq!(process_id, expected_process, "Process ID mismatch");
}
}
#[test]
fn lock_free_stress_8_threads() {
typedflake::id!(StressTestId);
const NUM_THREADS: usize = 8;
const IDS_PER_THREAD: usize = 1000;
let thread_results = run_concurrent_generation(NUM_THREADS, IDS_PER_THREAD, |thread_id| {
let instance = StressTestId::instance(thread_id as u64, 0).unwrap();
let mut ids = Vec::with_capacity(IDS_PER_THREAD);
for _ in 0..IDS_PER_THREAD {
ids.push(instance.generate());
}
assert_all_unique(&ids, &format!("Thread {thread_id} local uniqueness"));
ids
});
assert_global_uniqueness(thread_results, "8 threads × 1000 IDs");
}
#[test]
fn state_isolation_per_instance() {
typedflake::id!(IsolationTestId);
const NUM_INSTANCES: usize = 4;
const IDS_PER_INSTANCE: usize = 100;
let results = run_concurrent_generation(NUM_INSTANCES, IDS_PER_INSTANCE, |i| {
let worker_id = i as u64;
let process_id = (i * 2) as u64;
let instance = IsolationTestId::instance(worker_id, process_id).unwrap();
let mut ids = Vec::with_capacity(IDS_PER_INSTANCE);
for _ in 0..IDS_PER_INSTANCE {
ids.push(instance.generate());
}
assert_components_match(&ids, worker_id, process_id, |id| {
let c = id.components();
(c.worker_id, c.process_id)
});
let sequences: Vec<u64> = ids.iter().map(|id| id.sequence()).collect();
assert_eq!(
sequences[0], 0,
"Instance ({worker_id}, {process_id}) should start at 0"
);
let max_sequence = *sequences.iter().max().unwrap();
assert!(
max_sequence >= IDS_PER_INSTANCE as u64 / 2,
"Instance ({worker_id}, {process_id}) should have reasonable progression"
);
ids
});
assert_global_uniqueness(results, "Per-instance state isolation");
}
#[test]
fn concurrent_min_boundary() {
typedflake::id!(MinInstanceId);
const NUM_THREADS: usize = 4;
const IDS_PER_THREAD: usize = 250;
const WORKER_ID: u64 = 0;
const PROCESS_ID: u64 = 0;
let thread_results = run_concurrent_generation(NUM_THREADS, IDS_PER_THREAD, |_| {
let instance = MinInstanceId::instance(WORKER_ID, PROCESS_ID).unwrap();
(0..IDS_PER_THREAD).map(|_| instance.generate()).collect()
});
let all_ids: Vec<_> = thread_results.into_iter().flatten().collect();
assert_all_unique(&all_ids, "Concurrent min instance (0,0)");
assert_components_match(&all_ids, WORKER_ID, PROCESS_ID, |id| {
let c = id.components();
(c.worker_id, c.process_id)
});
}
#[test]
fn concurrent_max_boundary() {
typedflake::id!(MaxInstanceId);
const NUM_THREADS: usize = 4;
const IDS_PER_THREAD: usize = 250;
const WORKER_ID: u64 = 31; const PROCESS_ID: u64 = 31;
let thread_results = run_concurrent_generation(NUM_THREADS, IDS_PER_THREAD, |_| {
let instance = MaxInstanceId::instance(WORKER_ID, PROCESS_ID).unwrap();
(0..IDS_PER_THREAD).map(|_| instance.generate()).collect()
});
let all_ids: Vec<_> = thread_results.into_iter().flatten().collect();
assert_all_unique(&all_ids, "Concurrent max instance (31,31)");
assert_components_match(&all_ids, WORKER_ID, PROCESS_ID, |id| {
let c = id.components();
(c.worker_id, c.process_id)
});
}
#[test]
fn extreme_stress_16_threads() {
typedflake::id!(ExtremeStressId);
const NUM_THREADS: usize = 16;
const IDS_PER_THREAD: usize = 1000;
const WORKER_ID: u64 = 5;
const PROCESS_ID: u64 = 3;
let thread_results =
run_concurrent_generation(NUM_THREADS, IDS_PER_THREAD, move |thread_idx| {
let instance = ExtremeStressId::instance(WORKER_ID, PROCESS_ID).unwrap();
let mut ids = Vec::with_capacity(IDS_PER_THREAD);
for _ in 0..IDS_PER_THREAD {
ids.push(instance.generate());
}
assert_all_unique(&ids, &format!("Thread {thread_idx} local uniqueness"));
ids
});
let all_ids: Vec<_> = thread_results.into_iter().flatten().collect();
assert_all_unique(&all_ids, "Extreme stress global uniqueness");
assert_components_match(&all_ids, WORKER_ID, PROCESS_ID, |id| {
let c = id.components();
(c.worker_id, c.process_id)
});
println!(
"Extreme stress: {} total IDs generated across {} threads",
all_ids.len(),
NUM_THREADS
);
assert_eq!(all_ids.len(), NUM_THREADS * IDS_PER_THREAD);
}