summaryrefslogtreecommitdiffstats
path: root/src/remake/api.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-10-26 05:35:40 +0100
committertv <tv@krebsco.de>2026-10-26 05:35:40 +0100
commit504435444c65efc59c0f7c6881991296258538a7 (patch)
treef3cee5730f02c6c42ae1def4b2cbd22faf8e6a62 /src/remake/api.rs
parentc14ee0a0aa4e897a2c9fd7706d3df2255da12a1a (diff)
allow humand-friendly durations in API
Diffstat (limited to 'src/remake/api.rs')
-rw-r--r--src/remake/api.rs35
1 files changed, 28 insertions, 7 deletions
diff --git a/src/remake/api.rs b/src/remake/api.rs
index 41d72ad..f5063e0 100644
--- a/src/remake/api.rs
+++ b/src/remake/api.rs
@@ -19,11 +19,12 @@
//! Request body for POST (all optional; `baseHeads` not for `compact`, whose base is
//! fixed when it commits):
//! `{ "kind": "compact", "spec": null, "baseHeads": ["<hex>", …],
-//! "replayWindow": {"epochs": 1, "seconds": 604800},
-//! "archiveRetention": {"epochs": 2, "seconds": 2592000},
+//! "replayWindow": {"epochs": 1, "age": "7d"},
+//! "archiveRetention": {"epochs": 2, "age": "30d"},
//! "settle": "8m", "switchDelay": "1m" }`
//!
-//! `settle` and `switchDelay` are durations (`units`: seconds, or e.g. `500ms`, `8m`).
+//! `settle`, `switchDelay` and the retentions' `age` are durations (`units`: seconds,
+//! or e.g. `500ms`, `8m`, `7d`).
//!
//! `?force=` overrides checks: `true` all of them, or a comma-separated list of
//! * `switchDelay`: accept one below a keepalive interval (for tests and debugging,
@@ -164,8 +165,8 @@ struct StartRequest {
/// them are carried over. The current heads if absent. For a remake derived from
/// a read, use the heads that read returned (`GET /store?heads=true`).
base_heads: Option<Vec<String>>,
- replay_window: Option<Retention>,
- archive_retention: Option<Retention>,
+ replay_window: Option<RetentionRequest>,
+ archive_retention: Option<RetentionRequest>,
/// How long votes are collected; twice the dormancy threshold if absent.
#[serde(default, with = "crate::units::optional_duration")]
settle: Option<Duration>,
@@ -175,6 +176,26 @@ struct StartRequest {
switch_delay: Option<Duration>,
}
+/// A retention as a request gives it: the age as a duration.
+#[derive(Debug, Default, Deserialize)]
+#[serde(rename_all = "camelCase", deny_unknown_fields)]
+struct RetentionRequest {
+ epochs: Option<u64>,
+ #[serde(default, with = "crate::units::optional_duration")]
+ age: Option<Duration>,
+}
+
+impl From<RetentionRequest> for Retention {
+ fn from(request: RetentionRequest) -> Self {
+ Retention {
+ epochs: request.epochs,
+ age_ms: request
+ .age
+ .map(|age| u64::try_from(age.as_millis()).unwrap_or(u64::MAX)),
+ }
+ }
+}
+
/// What `?force=` may override on a proposal (`force`).
const FORCE: &[&str] = &["switchDelay", "supersede", "coordinatorActive"];
/// What `?force=` may override on an abort.
@@ -488,10 +509,10 @@ async fn start_kind<H: Host>(
policy: Policy {
replay_window: request
.replay_window
- .unwrap_or_else(Policy::default_replay_window),
+ .map_or_else(Policy::default_replay_window, Retention::from),
archive_retention: request
.archive_retention
- .unwrap_or_else(Policy::default_archive_retention),
+ .map_or_else(Policy::default_archive_retention, Retention::from),
},
settle_ms,
proposed_at: now,