use std::sync::mpsc;
use std::sync::Arc;
use std::thread;
use wireshift_core::backend::{Backend, BackendSubmission, CancellationHandle};
use wireshift_core::config::RingConfig;
use wireshift_core::op::OpDescriptor;
use wireshift_fallback::FallbackBackend;
#[test]
fn test_depth_concurrent_32_threads_hammer_api() {
let (tx, rx) = mpsc::channel();
let config = RingConfig::default()
.with_fallback_threads(32)
.with_queue_depth(1024);
let backend = Arc::new(FallbackBackend::new(&config, tx).unwrap());
let num_threads = 32;
let ops_per_thread = 1_000;
let mut join_handles = vec![];
for thread_idx in 0..num_threads {
let backend_clone = backend.clone();
let handle = thread::spawn(move || {
for op_idx in 0..ops_per_thread {
let id = thread_idx * ops_per_thread + op_idx;
let mut retry_count = 0;
loop {
let submission = BackendSubmission { id, descriptor: OpDescriptor::Nop, timeout: None };
let result = backend_clone.submit(submission);
match result {
Ok(_) => break,
Err(e) => {
if format!("{:?}", e).contains("queue is full") {
retry_count += 1;
assert!(retry_count < 100, "Queue remained full for too long");
thread::yield_now();
} else {
panic!("Unexpected submit error: {:?}", e);
}
}
}
}
if id % 10 == 0 {
let cancellation = CancellationHandle { target: id };
let _cancel_result = backend_clone.cancel(cancellation);
}
}
});
join_handles.push(handle);
}
for handle in join_handles {
handle.join().unwrap();
}
backend.shutdown().unwrap();
let total_expected = num_threads * ops_per_thread;
let mut completed = 0;
while let Ok(completion) = rx.try_recv() {
completed += 1;
match completion.result {
Ok(payload) => assert!(
matches!(payload, wireshift_core::op::CompletionPayload::Unit),
"Expected Nop payload"
),
Err(e) => {
assert!(
format!("{:?}", e).contains("canceled before"),
"Only cancellation errors expected, got {:?}",
e
);
}
}
}
assert_eq!(
completed, total_expected,
"Not all operations completed or returned a cancellation payload"
);
}