relay_system/runtime/
runtime.rs

1use std::future::Future;
2use std::sync::Arc;
3use std::time::Duration;
4
5use crate::Handle;
6use crate::runtime::metrics::TokioCallbackMetrics;
7
8/// A Relay async runtime.
9///
10/// This is a thin wrapper around a Tokio [`tokio::runtime::Runtime`],
11/// configured for Relay.
12pub struct Runtime {
13    rt: tokio::runtime::Runtime,
14    handle: Handle,
15}
16
17impl Runtime {
18    /// Creates a [`Builder`] to create and configure a new runtime.
19    pub fn builder(name: &'static str) -> Builder {
20        Builder::new(name)
21    }
22
23    /// Returns a [`Handle`] to this runtime.
24    ///
25    /// The [`Handle`] can be freely cloned and used to spawn services.
26    pub fn handle(&self) -> &Handle {
27        &self.handle
28    }
29
30    /// Runs a future to completion on this runtime.
31    ///
32    /// See also: [`tokio::runtime::Runtime::block_on`].
33    #[track_caller]
34    pub fn block_on<F: Future>(&self, future: F) -> F::Output {
35        self.rt.block_on(future)
36    }
37}
38
39/// Configures a Relay [`Runtime`].
40pub struct Builder {
41    name: &'static str,
42    builder: tokio::runtime::Builder,
43}
44
45impl Builder {
46    fn new(name: &'static str) -> Self {
47        let mut builder = tokio::runtime::Builder::new_multi_thread();
48        builder.thread_name(name).enable_all();
49
50        Self { name, builder }
51    }
52
53    /// Configures the amount of worker threads available to the runtime.
54    ///
55    /// The default value is the number of cores available to the system.
56    ///
57    /// See also: [`tokio::runtime::Builder::worker_threads`].
58    pub fn worker_threads(&mut self, num: usize) -> &mut Self {
59        self.builder.worker_threads(num);
60        self
61    }
62
63    /// Configures the amount of threads in the dynamic thread pool of the runtime.
64    ///
65    /// See also: [`tokio::runtime::Builder::max_blocking_threads`].
66    pub fn max_blocking_threads(&mut self, num: usize) -> &mut Self {
67        self.builder.max_blocking_threads(num);
68        self
69    }
70
71    /// Configures the idle timeout of threads in the dynamic thread pool.
72    ///
73    /// See also: [`tokio::runtime::Builder::thread_keep_alive`].
74    pub fn thread_keep_alive(&mut self, duration: Duration) -> &mut Self {
75        self.builder.thread_keep_alive(duration);
76        self
77    }
78
79    /// Creates the configured [`Runtime`].
80    pub fn build(&mut self) -> Runtime {
81        let tokio_cb_metrics = Arc::new(TokioCallbackMetrics::default());
82        tokio_cb_metrics.register(&mut self.builder);
83
84        let rt = self
85            .builder
86            .build()
87            .expect("creating the Tokio runtime should never fail");
88
89        Runtime {
90            handle: Handle::new(self.name, rt.handle().clone(), tokio_cb_metrics),
91            rt,
92        }
93    }
94}