aion/runtime/config.rs
1//! Builder-supplied scheduler configuration for the embedded runtime.
2
3use std::time::Duration;
4
5/// Configuration used when constructing the embedded BEAM runtime.
6#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
7pub struct RuntimeConfig {
8 /// Optional scheduler thread count supplied by the engine builder.
9 ///
10 /// `None` is passed through to beamr so the embedded runtime applies its own
11 /// runtime-aware default.
12 pub thread_count: Option<usize>,
13
14 /// Bounded readiness and retry policy for live signal mailbox delivery.
15 pub signal_delivery: SignalDeliveryConfig,
16
17 /// Whether the durable-outbox fan-out dispatch path is enabled.
18 pub outbox_enabled: bool,
19}
20
21/// Bounded signal delivery retry policy supplied by engine configuration.
22#[derive(Clone, Copy, Debug, Eq, PartialEq)]
23pub struct SignalDeliveryConfig {
24 /// Maximum time to wait for a just-spawned process body to materialize.
25 pub ready_timeout: Duration,
26
27 /// Maximum number of mailbox enqueue attempts after the ready gate.
28 pub max_enqueue_attempts: u32,
29
30 /// Initial sleep between failed enqueue attempts.
31 pub initial_backoff: Duration,
32
33 /// Upper bound for exponential backoff between enqueue attempts.
34 pub max_backoff: Duration,
35}
36
37impl Default for SignalDeliveryConfig {
38 fn default() -> Self {
39 Self::new(
40 Duration::from_millis(50),
41 8,
42 Duration::from_millis(1),
43 Duration::from_millis(8),
44 )
45 }
46}
47
48impl SignalDeliveryConfig {
49 /// Create an explicit signal delivery policy.
50 #[must_use]
51 pub const fn new(
52 ready_timeout: Duration,
53 max_enqueue_attempts: u32,
54 initial_backoff: Duration,
55 max_backoff: Duration,
56 ) -> Self {
57 Self {
58 ready_timeout,
59 max_enqueue_attempts,
60 initial_backoff,
61 max_backoff,
62 }
63 }
64
65 /// Bound for draining the single cleanup worker after every registered
66 /// process has been force-unblocked.
67 ///
68 /// A zero process-readiness bound is valid for refusal tests, but is not a
69 /// useful thread-shutdown observation window. Use at least the standard
70 /// readiness window and scale it by every job the worker can own (one
71 /// running plus the bounded queue) rather than imposing an unrelated
72 /// timeout constant.
73 pub(crate) fn cleanup_shutdown_timeout(self) -> Duration {
74 self.ready_timeout
75 .max(Self::default().ready_timeout)
76 .saturating_mul(self.max_enqueue_attempts.max(1).saturating_add(1))
77 }
78}
79
80impl RuntimeConfig {
81 /// Create runtime configuration from the builder-supplied scheduler count.
82 #[must_use]
83 pub fn new(thread_count: Option<usize>) -> Self {
84 Self {
85 thread_count,
86 signal_delivery: SignalDeliveryConfig::default(),
87 outbox_enabled: false,
88 }
89 }
90
91 /// Override the signal delivery retry policy.
92 #[must_use]
93 pub const fn with_signal_delivery(mut self, signal_delivery: SignalDeliveryConfig) -> Self {
94 self.signal_delivery = signal_delivery;
95 self
96 }
97
98 /// Override whether the durable-outbox fan-out dispatch path is enabled.
99 #[must_use]
100 pub const fn with_outbox_enabled(mut self, enabled: bool) -> Self {
101 self.outbox_enabled = enabled;
102 self
103 }
104}