From 223834c9dabdab00fceda69b9ce989995de47efa Mon Sep 17 00:00:00 2001 From: tv Date: Mon, 26 Oct 2026 05:24:32 +0100 Subject: remove unit suffixes from fields --- src/remake/api.rs | 57 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 27 deletions(-) (limited to 'src/remake/api.rs') diff --git a/src/remake/api.rs b/src/remake/api.rs index 515468d..ab1b01b 100644 --- a/src/remake/api.rs +++ b/src/remake/api.rs @@ -5,7 +5,7 @@ //! node becomes its coordinator. `202` with the report, or with `?wait=true` the final //! report once decided. A dropped request does not abort anything. The remake //! commits as soon as a majority of its electorate voted for it (`vote`), and aborts -//! once that is out of reach or `settleSecs` passed without it. +//! once that is out of reach or `settle` passed without it. //! * `GET /admin/remakes` lists all remakes. //! * `GET /admin/remakes/{id}` reports one; `?wait=true` long-polls until decided //! (bounded by the proposal's own expiry). @@ -22,10 +22,12 @@ //! `{ "kind": "compact", "spec": null, "baseHeads": ["", …], //! "replayWindow": {"epochs": 1, "seconds": 604800}, //! "archiveRetention": {"epochs": 2, "seconds": 2592000}, -//! "settleSecs": 480, "switchDelaySecs": 60 }` +//! "settle": "8m", "switchDelay": "1m" }` +//! +//! `settle` and `switchDelay` are durations (`units`: seconds, or e.g. `500ms`, `8m`). //! //! `?force=` overrides checks: `true` all of them, or a comma-separated list of -//! * `switchDelaySecs`: accept one below a keepalive interval (for tests and debugging, +//! * `switchDelay`: accept one below a keepalive interval (for tests and debugging, //! not for real swarms); //! * `supersede`: abort expired remakes of this epoch and propose in their place. //! Without it, an expired remake still holding votes answers `409`. @@ -39,8 +41,8 @@ //! downloads it (`content`). Requests may be up to 64 MiB. //! //! An import can also be uploaded as is, with `Content-Type: application/octet-stream`; -//! then `rules` (JSON), `baseHeads` (comma-separated), `settleSecs` and -//! `switchDelaySecs` go in the query. Restoring a backup, keeping writes made since at +//! then `rules` (JSON), `baseHeads` (comma-separated), `settle` and `switchDelay` go +//! in the query. Restoring a backup, keeping writes made since at //! their paths: //! `curl --data-binary @backup.automerge -H 'Content-Type: application/octet-stream' --url-query 'rules=[{"from":"","to":""}]' …/admin/remakes` @@ -103,16 +105,18 @@ pub(crate) struct StartQuery { rules: Option, /// Comma-separated hex. base_heads: Option, - settle_secs: Option, - switch_delay_secs: Option, + #[serde(default, with = "crate::units::optional_duration")] + settle: Option, + #[serde(default, with = "crate::units::optional_duration")] + switch_delay: Option, } impl StartQuery { fn has_request_fields(&self) -> bool { self.rules.is_some() || self.base_heads.is_some() - || self.settle_secs.is_some() - || self.switch_delay_secs.is_some() + || self.settle.is_some() + || self.switch_delay.is_some() } /// An import request for a document uploaded as is. @@ -135,8 +139,8 @@ impl StartQuery { .map(str::to_owned) .collect() }), - settle_secs: self.settle_secs, - switch_delay_secs: self.switch_delay_secs, + settle: self.settle, + switch_delay: self.switch_delay, ..StartRequest::default() }) } @@ -164,14 +168,16 @@ struct StartRequest { replay_window: Option, archive_retention: Option, /// How long votes are collected; twice the dormancy threshold if absent. - settle_secs: Option, + #[serde(default, with = "crate::units::optional_duration")] + settle: Option, /// How long nodes wait after seeing the commit before switching; one keepalive - /// interval if absent. Shorter only with `?force=switchDelaySecs`. - switch_delay_secs: Option, + /// interval if absent. Shorter only with `?force=switchDelay`. + #[serde(default, with = "crate::units::optional_duration")] + switch_delay: Option, } /// What `?force=` may override on a proposal (`force`). -const FORCE: &[&str] = &["switchDelaySecs", "supersede", "coordinatorActive"]; +const FORCE: &[&str] = &["switchDelay", "supersede", "coordinatorActive"]; /// What `?force=` may override on an abort. const ABORT_FORCE: &[&str] = &["coordinatorActive"]; @@ -387,7 +393,7 @@ async fn start_kind( } else if query.has_request_fields() { return error_response( StatusCode::BAD_REQUEST, - "rules, baseHeads, settleSecs and switchDelaySecs go in the query only for an application/octet-stream import; put them in the JSON body", + "rules, baseHeads, settle and switchDelay go in the query only for an application/octet-stream import; put them in the JSON body", None, ); } else if body.is_empty() { @@ -461,20 +467,17 @@ async fn start_kind( // The voting period. No lower bound: the majority protects against competitors, // a short period only risks an abort for lack of votes. let dormant_after = host.dormant_after(); - let settle = request - .settle_secs - .map(Duration::from_secs) - .unwrap_or(dormant_after * 2); + let settle = request.settle.unwrap_or(dormant_after * 2); // The delay lets the commit reach every node through ordinary sync before any of // them stops syncing the old epoch. let keepalive = dormant_after / 4; - let switch_delay = request.switch_delay_secs.map(Duration::from_secs); + let switch_delay = request.switch_delay; match switch_delay { - Some(delay) if delay < keepalive && force.allows("switchDelaySecs") => { + Some(delay) if delay < keepalive && force.allows("switchDelay") => { warn!( - switch_delay_secs = delay.as_secs(), - keepalive_secs = keepalive.as_secs(), + switch_delay = %crate::units::format_duration(delay), + keepalive = %crate::units::format_duration(keepalive), "Forced switch delay shorter than a keepalive interval; slow nodes may have to rejoin" ); } @@ -482,8 +485,8 @@ async fn start_kind( return error_response( StatusCode::BAD_REQUEST, format!( - "switchDelaySecs must be at least {} (one keepalive interval), so the commit reaches every node before they switch; add ?force=switchDelaySecs to override", - keepalive.as_secs() + "switchDelay must be at least {} (one keepalive interval), so the commit reaches every node before they switch; add ?force=switchDelay to override", + crate::units::format_duration(keepalive) ), None, ); @@ -607,7 +610,7 @@ async fn start_kind( info!( remake = %id, - settle_secs = settle.as_secs(), + settle = %crate::units::format_duration(settle), "Remake proposed" ); -- cgit v1.3.1