Skip to main content

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}