turmoil/
config.rs

1use rand_distr::Exp;
2use std::{
3    ops::RangeInclusive,
4    time::{Duration, SystemTime},
5};
6
7/// Configuration for a simulation.
8///
9/// This configuration allows you to define different aspects of how the
10/// simulation should run, such as the duration, or the tick rate.
11///
12/// ## Default values
13///
14/// The config provides a default of:
15/// - duration: 10 seconds
16/// - tick: 1ms
17/// - epoch: the current system time
18/// - ephemeral_ports: 49152..=65535
19/// - tcp_capacity: 64
20/// - udp_capacity: 64
21#[derive(Clone)]
22pub(crate) struct Config {
23    /// How long the test should run for in simulated time.
24    pub(crate) duration: Duration,
25
26    /// How much simulated time should elapse each tick
27    pub(crate) tick: Duration,
28
29    /// When the simulation starts
30    pub(crate) epoch: SystemTime,
31
32    pub(crate) ephemeral_ports: RangeInclusive<u16>,
33
34    /// Max size of the tcp receive buffer
35    pub(crate) tcp_capacity: usize,
36
37    /// Max size of the udp receive buffer
38    pub(crate) udp_capacity: usize,
39
40    /// Enables tokio IO driver
41    pub(crate) enable_tokio_io: bool,
42
43    /// Enables running of host/client code in random order at each
44    /// simulation step
45    pub(crate) random_node_order: bool,
46}
47
48/// Configures link behavior.
49#[derive(Clone, Default)]
50pub(crate) struct Link {
51    /// Message latency between two hosts
52    pub(crate) latency: Option<Latency>,
53
54    /// How often sending a message works vs. the message getting dropped
55    pub(crate) message_loss: Option<MessageLoss>,
56}
57
58/// Configure latency behavior between two hosts.
59///
60/// Provides default values of:
61/// - min_message_latency: 0ms
62/// - max_message_latency: 100ms
63/// - latency_distribution: Exp(5)
64#[derive(Clone)]
65pub(crate) struct Latency {
66    /// Minimum latency
67    pub(crate) min_message_latency: Duration,
68
69    /// Maximum latency
70    pub(crate) max_message_latency: Duration,
71
72    /// Probability distribution of latency within the range above.
73    pub(crate) latency_distribution: Exp<f64>,
74}
75
76/// Configure how often messages are lost.
77///
78/// Provides default values of 0% failure rate, and 100% repair rate.
79#[derive(Clone)]
80pub(crate) struct MessageLoss {
81    /// Probability of a link failing
82    pub(crate) fail_rate: f64,
83
84    /// Probability of a failed link returning
85    pub(crate) repair_rate: f64,
86}
87
88impl Default for Config {
89    fn default() -> Config {
90        Config {
91            duration: Duration::from_secs(10),
92            tick: Duration::from_millis(1),
93            epoch: SystemTime::now(),
94            ephemeral_ports: 49152..=65535,
95            tcp_capacity: 64,
96            udp_capacity: 64,
97            enable_tokio_io: false,
98            random_node_order: false,
99        }
100    }
101}
102
103impl Link {
104    pub(crate) fn latency(&self) -> &Latency {
105        self.latency.as_ref().expect("`Latency` missing")
106    }
107
108    pub(crate) fn latency_mut(&mut self) -> &mut Latency {
109        self.latency.as_mut().expect("`Latency` missing")
110    }
111
112    pub(crate) fn message_loss(&self) -> &MessageLoss {
113        self.message_loss.as_ref().expect("`MessageLoss` missing")
114    }
115
116    pub(crate) fn message_loss_mut(&mut self) -> &mut MessageLoss {
117        self.message_loss.as_mut().expect("`MessageLoss` missing")
118    }
119}
120
121impl Default for Latency {
122    fn default() -> Latency {
123        Latency {
124            min_message_latency: Duration::from_millis(0),
125            max_message_latency: Duration::from_millis(100),
126            latency_distribution: Exp::new(5.0).unwrap(),
127        }
128    }
129}
130
131impl Default for MessageLoss {
132    fn default() -> MessageLoss {
133        MessageLoss {
134            fail_rate: 0.0,
135            repair_rate: 1.0,
136        }
137    }
138}