Skip to main content

krabka_raft/config/
limits.rs

1//! The validated scalar policies a controller's runtime is spelled in.
2//!
3//! `ControllerFetchMissLimit`, `MetadataRaftCommandQueueCapacity`, and
4//! `MetadataRaftFetchMax` each wrap one number that has to stay in range, so a
5//! value the broker's configuration names is refused where it is parsed rather
6//! than where it is used. They live apart from `ControllerConfig` because the
7//! validation, the `FromStr` the configuration file goes through, and the
8//! `Display` that renders the value back are a concern of their own. The
9//! defaults they fall back to stay with the rest of the configuration
10//! defaults, in the parent module.
11
12use {
13    super::{
14        DEFAULT_CONTROLLER_FETCH_MISS_LIMIT, DEFAULT_METADATA_RAFT_COMMAND_QUEUE_CAPACITY,
15        DEFAULT_METADATA_RAFT_FETCH_MAX,
16    },
17    krabka_macros::RefinedNewtype,
18    refined_type::rule::{GreaterI32, GreaterU32, GreaterUsize},
19};
20
21#[derive(derive_more::From, derive_more::Into)]
22/// The number of consecutive fetch misses a controller tolerates.
23#[derive(Clone, Copy, Debug, Eq, PartialEq, RefinedNewtype)]
24#[refined(
25    rule(GreaterU32<0>),
26    string_error,
27    label = "controller fetch miss limit",
28    getter = get,
29    default = DEFAULT_CONTROLLER_FETCH_MISS_LIMIT,
30    from_str,
31    display
32)]
33pub struct ControllerFetchMissLimit(u32);
34
35#[derive(derive_more::From, derive_more::Into)]
36/// The capacity of the metadata Raft command queue.
37#[derive(Clone, Copy, Debug, Eq, PartialEq, RefinedNewtype)]
38#[refined(
39    rule(GreaterUsize<0>),
40    string_error,
41    label = "metadata raft command queue capacity",
42    getter = get,
43    default = DEFAULT_METADATA_RAFT_COMMAND_QUEUE_CAPACITY,
44    from_str,
45    display
46)]
47pub struct MetadataRaftCommandQueueCapacity(usize);
48
49#[derive(derive_more::From, derive_more::Into)]
50/// The most bytes one metadata Raft fetch carries, a whole byte count that
51/// fits the protocol's `int32` field.
52#[derive(Clone, Copy, Debug, Eq, PartialEq, RefinedNewtype)]
53#[refined(
54    rule(GreaterI32<0>),
55    quantity = ByteSize,
56    label = "metadata raft fetch max",
57    getter = bytes,
58    quantity_getter = size,
59    default = DEFAULT_METADATA_RAFT_FETCH_MAX,
60    from_str,
61    display
62)]
63pub struct MetadataRaftFetchMax(i32);
64
65#[cfg(test)]
66mod tests {
67    use {
68        super::*,
69        assert2::check,
70        krabka_units::prelude::{ByteSize, ByteSizeExt as _, mebibytes},
71    };
72
73    #[test]
74    fn raft_runtime_policy_defaults_and_validation() {
75        check!(ControllerFetchMissLimit::default().get() == 3);
76        check!(ControllerFetchMissLimit::new(0).is_err());
77        check!(
78            "7".parse::<ControllerFetchMissLimit>()
79                .expect("positive miss limit")
80                .get()
81                == 7
82        );
83
84        check!(MetadataRaftCommandQueueCapacity::default().get() == 256);
85        check!(MetadataRaftCommandQueueCapacity::new(0).is_err());
86        check!(
87            "512"
88                .parse::<MetadataRaftCommandQueueCapacity>()
89                .expect("positive command queue capacity")
90                .get()
91                == 512
92        );
93
94        check!(MetadataRaftFetchMax::default().size() == mebibytes(8));
95        check!(MetadataRaftFetchMax::try_from(ByteSize::from_bytes_i64(0)).is_err());
96        check!(
97            "4MiB"
98                .parse::<MetadataRaftFetchMax>()
99                .expect("positive whole-byte fetch maximum")
100                .bytes()
101                == 4 * 1024 * 1024
102        );
103        check!(MetadataRaftFetchMax::try_from(ByteSize::from_bytes_f64(1.5)).is_err());
104        check!(
105            MetadataRaftFetchMax::try_from(ByteSize::from_bytes_i64(i64::from(i32::MAX) + 1))
106                .is_err()
107        );
108        check!(format!("{}", ControllerFetchMissLimit::default()) == "3");
109        check!(format!("{}", MetadataRaftCommandQueueCapacity::default()) == "256");
110        check!(format!("{}", MetadataRaftFetchMax::default()) == "8MiB");
111    }
112}