1use std::sync::atomic::AtomicUsize;
2
3use crate::{runtime::LevelRuntime, worker::LevelWorker};
4
5pub struct Builder {
10 builder: tokio::runtime::Builder,
11 worker_threads: usize,
12 thread_name: std::sync::Arc<dyn Fn() -> String + Send + Sync + 'static>,
13}
14
15impl Default for Builder {
16 fn default() -> Self {
17 Self {
18 worker_threads: 1,
19 builder: tokio::runtime::Builder::new_current_thread(),
20 thread_name: std::sync::Arc::new(|| {
21 static I: AtomicUsize = AtomicUsize::new(0);
22 let i = I.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
23 format!("level-{i:02}")
24 }),
25 }
26 }
27}
28
29impl Builder {
30 pub fn build(&mut self) -> LevelRuntime {
32 LevelRuntime::from_workers(
33 self.thread_name.clone(),
34 (0..self.worker_threads)
35 .map(|_i| {
36 self.builder
37 .build()
38 .expect("must be able to build tokio runtime")
39 })
40 .map(LevelWorker::from_runtime)
41 .collect(),
42 )
43 }
44
45 pub fn worker_threads(&mut self, threads: usize) -> &mut Self {
47 self.worker_threads = threads;
48 self
49 }
50
51 pub fn thread_name_prefix(&mut self, name: impl Into<String>) -> &mut Self {
53 let mut name = name.into();
54 if 12 < name.len() {
55 name.truncate(12);
56 log::warn!("truncating thread name prefix to 12 characters: {name}")
62 }
63 let name_i: AtomicUsize = AtomicUsize::new(0);
64 self.thread_name = std::sync::Arc::new(move || {
65 let i = name_i.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
66 format!("{name}-{i:02}")
67 });
68 self
69 }
70
71 pub fn enable_all(&mut self) -> &mut Self {
73 self.builder.enable_all();
74 self
75 }
76
77 pub fn event_interval(&mut self, interval: u32) -> &mut Self {
79 self.builder.event_interval(interval);
80 self
81 }
82
83 pub fn global_queue_interval(&mut self, interval: u32) -> &mut Self {
85 self.builder.global_queue_interval(interval);
86 self
87 }
88
89 pub fn max_io_events_per_tick(&mut self, capacity: usize) -> &mut Self {
91 self.builder.max_io_events_per_tick(capacity);
92 self
93 }
94
95 pub fn max_blocking_threads(&mut self, capacity: usize) -> &mut Self {
97 self.builder.max_blocking_threads(capacity);
98 self
99 }
100
101 pub fn on_thread_park(&mut self, f: impl Fn() + Send + Sync + 'static) -> &mut Self {
103 self.builder.on_thread_park(f);
104 self
105 }
106
107 pub fn on_thread_unpark(&mut self, f: impl Fn() + Send + Sync + 'static) -> &mut Self {
109 self.builder.on_thread_unpark(f);
110 self
111 }
112}