throttle: serialize in string notation

Prior to exposing max_burst in the throttle string parser, we
couldn't guarantee to represent any arbitrary throttle as a string,
so we serialized as the underlying struct fields.

That's a bit unwieldy to read, so let's switch to the string
representation.

This commit makes the string repr infallible (previously it could fail
if you had specified max_burst), then tackles the fanout from that.

Apparently none of our snapshot tests include any of these throttles,
so I manually spot checked it with `kcli inspect-sched-q` to observe
the `max_message_rate`.
This commit is contained in:
Wez Furlong
2025-01-29 10:57:18 -07:00
parent 04a1777727
commit 3da38d986e
2 changed files with 26 additions and 34 deletions
+10 -16
View File
@@ -1219,22 +1219,16 @@ impl ProviderEntry {
);
}
if let Some(rate) = &self.provider_max_message_rate {
match rate.as_string() {
Ok(rate) => {
let mut limits = toml::Table::new();
limits.insert(
format!("shaping-provider-{}-{source}-rate", self.provider_name),
rate.into(),
);
implied.insert(
"additional_message_rate_throttles".to_string(),
toml::Value::Table(limits),
);
}
Err(err) => {
tracing::error!("Error representing provider_max_message_rate: {err}");
}
}
let rate = rate.as_string();
let mut limits = toml::Table::new();
limits.insert(
format!("shaping-provider-{}-{source}-rate", self.provider_name),
rate.into(),
);
implied.insert(
"additional_message_rate_throttles".to_string(),
toml::Value::Table(limits),
);
}
toml_table_merge_from(target, &implied);
+16 -18
View File
@@ -82,7 +82,7 @@ pub enum Error {
}
#[derive(Eq, PartialEq, Clone, Copy, Serialize, Deserialize, Hash)]
#[serde(try_from = "String")]
#[serde(try_from = "String", into = "String")]
pub struct ThrottleSpec {
pub limit: u64,
/// Period, in seconds
@@ -129,24 +129,18 @@ impl ThrottleSpec {
impl std::fmt::Debug for ThrottleSpec {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
match self.as_string() {
Ok(s) => write!(fmt, "{}", s),
Err(_) => Err(std::fmt::Error),
}
write!(fmt, "{}", self.as_string())
}
}
impl std::fmt::Display for ThrottleSpec {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
match self.as_string() {
Ok(s) => write!(fmt, "{}", s),
Err(_) => Err(std::fmt::Error),
}
write!(fmt, "{}", self.as_string())
}
}
impl ThrottleSpec {
pub fn as_string(&self) -> Result<String, String> {
pub fn as_string(&self) -> String {
let mut period_scale = None;
let period = match self.period {
86400 => "d",
@@ -164,7 +158,7 @@ impl ThrottleSpec {
None => String::new(),
};
Ok(format!(
format!(
"{}{}/{}{period}{burst}",
if self.force_local { "local:" } else { "" },
self.limit,
@@ -172,7 +166,13 @@ impl ThrottleSpec {
Some(scale) => scale.as_str(),
None => "",
}
))
)
}
}
impl From<ThrottleSpec> for String {
fn from(spec: ThrottleSpec) -> String {
spec.as_string()
}
}
@@ -519,8 +519,7 @@ mod test {
max_burst: None,
force_local: false,
}
.as_string()
.unwrap(),
.as_string(),
"100/h"
);
assert_eq!(
@@ -530,8 +529,7 @@ mod test {
max_burst: None,
force_local: true,
}
.as_string()
.unwrap(),
.as_string(),
"local:100/h"
);
@@ -545,7 +543,7 @@ mod test {
force_local: true,
}
);
assert_eq!(weird_duration.as_string().unwrap(), "local:100/7380s");
assert_eq!(weird_duration.as_string(), "local:100/7380s");
assert_eq!(
ThrottleSpec::try_from("1_0,0/hour").unwrap(),
@@ -575,7 +573,7 @@ mod test {
force_local: false,
}
);
assert_eq!(burst.as_string().unwrap(), "50/d,max_burst=1");
assert_eq!(burst.as_string(), "50/d,max_burst=1");
}
#[test]