async_global_executor/
config.rs1use once_cell::sync::OnceCell;
2use std::{
3 fmt,
4 sync::atomic::{AtomicUsize, Ordering},
5};
6
7pub(crate) static GLOBAL_EXECUTOR_CONFIG: OnceCell<Config> = OnceCell::new();
8
9#[derive(Default)]
11pub struct GlobalExecutorConfig {
12 env_var: Option<&'static str>,
14 min_threads: Option<usize>,
16 max_threads: Option<usize>,
18 thread_name_fn: Option<Box<dyn Fn() -> String + Send + Sync>>,
20}
21
22impl fmt::Debug for GlobalExecutorConfig {
23 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24 f.debug_struct("GlobalExecutorConfig")
25 .field("env_var", &self.env_var)
26 .field("min_threads", &self.min_threads)
27 .field("max_threads", &self.max_threads)
28 .finish()
29 }
30}
31
32impl GlobalExecutorConfig {
33 pub fn with_env_var(mut self, env_var: &'static str) -> Self {
35 self.env_var = Some(env_var);
36 self
37 }
38
39 pub fn with_min_threads(mut self, min_threads: usize) -> Self {
41 self.min_threads = Some(min_threads);
42 self
43 }
44
45 pub fn with_max_threads(mut self, max_threads: usize) -> Self {
49 self.max_threads = Some(max_threads);
50 self
51 }
52
53 pub fn with_thread_name_fn(
55 mut self,
56 thread_name_fn: impl Fn() -> String + Send + Sync + 'static,
57 ) -> Self {
58 self.thread_name_fn = Some(Box::new(thread_name_fn));
59 self
60 }
61
62 pub(crate) fn seal(self) -> Config {
63 let min_threads = std::env::var(self.env_var.unwrap_or("ASYNC_GLOBAL_EXECUTOR_THREADS"))
64 .ok()
65 .and_then(|threads| threads.parse().ok())
66 .or(self.min_threads)
67 .unwrap_or_else(|| std::thread::available_parallelism().map_or(1, usize::from))
68 .max(1);
69 let max_threads = self.max_threads.unwrap_or(min_threads * 4).max(min_threads);
70 Config {
71 min_threads,
72 max_threads,
73 thread_name_fn: self.thread_name_fn.unwrap_or_else(|| {
74 Box::new(|| {
75 static GLOBAL_EXECUTOR_NEXT_THREAD: AtomicUsize = AtomicUsize::new(1);
76 format!(
77 "async-global-executor-{}",
78 GLOBAL_EXECUTOR_NEXT_THREAD.fetch_add(1, Ordering::SeqCst)
79 )
80 })
81 }),
82 }
83 }
84}
85
86pub(crate) struct Config {
88 pub(crate) min_threads: usize,
89 pub(crate) max_threads: usize,
90 pub(crate) thread_name_fn: Box<dyn Fn() -> String + Send + Sync>,
91}
92
93impl Default for Config {
94 fn default() -> Self {
95 GlobalExecutorConfig::default().seal()
96 }
97}