use diskann::{ANNError, ANNResult};
pub fn create_runtime(num_threads: usize) -> ANNResult<tokio::runtime::Runtime> {
let mut builder = tokio::runtime::Builder::new_multi_thread();
if num_threads != 0 {
builder.worker_threads(num_threads);
}
builder.build().map_err(|err| {
ANNError::log_index_error(format!("Failed to initialize tokio runtime: {}", err))
})
}
#[cfg(test)]
mod tests {
use super::*;
fn get_logical_cpu_count() -> usize {
std::thread::available_parallelism()
.map(|n| n.get())
.unwrap_or(1)
}
#[test]
fn test_create_runtime_with_zero_threads_no_panic() {
let result = create_runtime(0);
assert!(result.is_ok(), "create_runtime(0) should not panic or fail");
let runtime = result.unwrap();
let result = runtime.block_on(async { tokio::spawn(async { 42 }).await });
assert!(result.is_ok(), "Runtime should be functional");
assert_eq!(result.unwrap(), 42);
}
#[test]
fn test_create_runtime_with_specific_threads() {
let result = create_runtime(2);
assert!(result.is_ok(), "create_runtime(2) should succeed");
let runtime = result.unwrap();
let result = runtime.block_on(async { tokio::spawn(async { "test" }).await });
assert!(result.is_ok(), "Runtime should be functional");
assert_eq!(result.unwrap(), "test");
}
#[test]
fn test_create_runtime_with_one_thread() {
let result = create_runtime(1);
assert!(result.is_ok(), "create_runtime(1) should succeed");
let runtime = result.unwrap();
let result = runtime.block_on(async { tokio::spawn(async { true }).await });
assert!(
result.is_ok(),
"Single-threaded runtime should be functional"
);
assert!(result.unwrap());
}
#[test]
fn test_zero_threads_defaults_to_cpu_count() {
let expected_cpu_count = get_logical_cpu_count();
let result = create_runtime(0);
assert!(
result.is_ok(),
"create_runtime(0) should default to {} CPUs",
expected_cpu_count
);
let runtime = result.unwrap();
let result = runtime.block_on(async {
let tasks = (0..expected_cpu_count.min(4))
.map(|i| tokio::spawn(async move { i * 2 }))
.collect::<Vec<_>>();
let mut results = Vec::new();
for task in tasks {
results.push(task.await.unwrap());
}
results
});
assert!(
result.len() <= 4,
"Should handle concurrent tasks successfully"
);
}
}