hexz_store/runtime.rs
1//! Shared Tokio runtime for async storage backends.
2//!
3//! Lazily initialises a process-global multi-threaded runtime so that
4//! `HttpBackend` and `S3Backend` share one thread pool rather than each
5//! creating their own.
6
7use std::io;
8use std::sync::OnceLock;
9use tokio::runtime::{Handle, Runtime};
10
11static GLOBAL_RUNTIME: OnceLock<Runtime> = OnceLock::new();
12
13/// Returns a handle to the shared Tokio runtime, creating it on first call.
14///
15/// # Errors
16///
17/// Returns an I/O error if the Tokio runtime cannot be created (e.g. the OS
18/// cannot spawn worker threads).
19pub fn global_handle() -> io::Result<Handle> {
20 // OnceLock::get_or_init is infallible and doesn't propagate errors from
21 // the init closure, so we try to create the runtime and store it only on
22 // success. On repeated calls we just hand back the existing handle.
23 if let Some(rt) = GLOBAL_RUNTIME.get() {
24 return Ok(rt.handle().clone());
25 }
26 let rt = Runtime::new()?;
27 // Another thread may have raced us; that's fine — get_or_init returns
28 // whichever value was stored first.
29 Ok(GLOBAL_RUNTIME.get_or_init(|| rt).handle().clone())
30}