diff --git a/pageserver/src/config.rs b/pageserver/src/config.rs index 89fda958ff..66f4d56655 100644 --- a/pageserver/src/config.rs +++ b/pageserver/src/config.rs @@ -94,6 +94,8 @@ pub mod defaults { pub const DEFAULT_VALIDATE_VECTORED_GET: bool = true; + pub const DEFAULT_WALREDO_PROCESS_KIND: &str = crate::walredo::ProcessKind::DEFAULT_TOML; + /// /// Default built-in configuration file. /// @@ -136,6 +138,8 @@ pub mod defaults { #validate_vectored_get = '{DEFAULT_VALIDATE_VECTORED_GET}' +#walredo_process_kind = '{DEFAULT_WALREDO_PROCESS_KIND}' + [tenant_config] #checkpoint_distance = {DEFAULT_CHECKPOINT_DISTANCE} # in bytes #checkpoint_timeout = {DEFAULT_CHECKPOINT_TIMEOUT} @@ -274,6 +278,8 @@ pub struct PageServerConf { pub max_vectored_read_bytes: MaxVectoredReadBytes, pub validate_vectored_get: bool, + + pub walredo_process_kind: crate::walredo::ProcessKind, } /// We do not want to store this in a PageServerConf because the latter may be logged @@ -393,6 +399,8 @@ struct PageServerConfigBuilder { max_vectored_read_bytes: BuilderValue, validate_vectored_get: BuilderValue, + + walredo_process_kind: BuilderValue, } impl PageServerConfigBuilder { @@ -475,6 +483,8 @@ impl PageServerConfigBuilder { NonZeroUsize::new(DEFAULT_MAX_VECTORED_READ_BYTES).unwrap(), )), validate_vectored_get: Set(DEFAULT_VALIDATE_VECTORED_GET), + + walredo_process_kind: Set(DEFAULT_WALREDO_PROCESS_KIND.parse().unwrap()), } } } @@ -643,6 +653,10 @@ impl PageServerConfigBuilder { self.validate_vectored_get = BuilderValue::Set(value); } + pub fn get_walredo_process_kind(&mut self, value: crate::walredo::ProcessKind) { + self.walredo_process_kind = BuilderValue::Set(value); + } + pub fn build(self) -> anyhow::Result { let default = Self::default_values(); @@ -696,6 +710,7 @@ impl PageServerConfigBuilder { get_vectored_impl, max_vectored_read_bytes, validate_vectored_get, + walredo_process_kind, } CUSTOM LOGIC { @@ -982,6 +997,9 @@ impl PageServerConf { "validate_vectored_get" => { builder.get_validate_vectored_get(parse_toml_bool("validate_vectored_get", item)?) } + "walredo_process_kind" => { + builder.get_walredo_process_kind(parse_toml_from_str("walredo_process_kind", item)?) + } _ => bail!("unrecognized pageserver option '{key}'"), } } @@ -1061,6 +1079,7 @@ impl PageServerConf { .expect("Invalid default constant"), ), validate_vectored_get: defaults::DEFAULT_VALIDATE_VECTORED_GET, + walredo_process_kind: defaults::DEFAULT_WALREDO_PROCESS_KIND.parse().unwrap(), } } } @@ -1295,6 +1314,7 @@ background_task_maximum_delay = '334 s' .expect("Invalid default constant") ), validate_vectored_get: defaults::DEFAULT_VALIDATE_VECTORED_GET, + walredo_process_kind: defaults::DEFAULT_WALREDO_PROCESS_KIND.parse().unwrap(), }, "Correct defaults should be used when no config values are provided" ); @@ -1364,6 +1384,7 @@ background_task_maximum_delay = '334 s' .expect("Invalid default constant") ), validate_vectored_get: defaults::DEFAULT_VALIDATE_VECTORED_GET, + walredo_process_kind: defaults::DEFAULT_WALREDO_PROCESS_KIND.parse().unwrap(), }, "Should be able to parse all basic config values correctly" ); diff --git a/pageserver/src/walredo.rs b/pageserver/src/walredo.rs index ef0b96622c..c050bd9340 100644 --- a/pageserver/src/walredo.rs +++ b/pageserver/src/walredo.rs @@ -20,7 +20,7 @@ /// Process lifecycle and abstracction for the IPC protocol. mod process; -pub(crate) use process::{Kind as ProcessKind, set_kind as set_process_kind}; +pub(crate) use process::{set_kind as set_process_kind, Kind as ProcessKind}; /// Code to apply [`NeonWalRecord`]s. pub(crate) mod apply_neon; diff --git a/pageserver/src/walredo/process.rs b/pageserver/src/walredo/process.rs index a8d0cece0e..912923e9a0 100644 --- a/pageserver/src/walredo/process.rs +++ b/pageserver/src/walredo/process.rs @@ -9,7 +9,6 @@ use utils::lsn::Lsn; use crate::{config::PageServerConf, walrecord::NeonWalRecord}; -mod live_reconfig; mod no_leak_child; /// The IPC protocol that pageserver and walredo process speak over their shared pipe. mod protocol; @@ -19,9 +18,20 @@ mod process_impl { pub(super) mod process_std; } -#[derive(Clone, Copy, Debug, serde::Serialize, serde::Deserialize)] +#[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + strum_macros::EnumString, + strum_macros::Display, + serde_with::DeserializeFromStr, + serde_with::SerializeDisplay, +)] +#[strum(serialize_all = "kebab-case")] #[repr(u8)] -pub(crate) enum Kind { +pub enum Kind { Sync, Async, } @@ -38,7 +48,12 @@ impl TryFrom for Kind { } } -static PROCESS_KIND: AtomicU8 = AtomicU8::new(Kind::Async as u8); +impl Kind { + pub const DEFAULT: Kind = Kind::Sync; + pub const DEFAULT_TOML: &'static str = "sync"; +} + +static PROCESS_KIND: AtomicU8 = AtomicU8::new(Kind::DEFAULT as u8); pub(crate) fn set_kind(kind: Kind) { PROCESS_KIND.store(kind as u8, std::sync::atomic::Ordering::Relaxed); @@ -110,3 +125,24 @@ impl Process { } } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_ensure_defaults_are_eq() { + #[derive(serde::Serialize, serde::Deserialize, Clone, Copy, Debug, PartialEq, Eq)] + struct Doc { + val: Kind, + } + let de = Doc { val: Kind::DEFAULT }; + let default_toml = Kind::DEFAULT_TOML; + let ser = format!( + r#" + val = '{default_toml}' + "# + ); + assert_eq!(de, toml_edit::de::from_str(&ser).unwrap(),); + } +} diff --git a/pageserver/src/walredo/process/live_reconfig.rs b/pageserver/src/walredo/process/live_reconfig.rs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/pageserver/src/walredo/process/process_impl/process_async.rs b/pageserver/src/walredo/process/process_impl/process_async.rs index d6bbcb374e..fa90a08aaa 100644 --- a/pageserver/src/walredo/process/process_impl/process_async.rs +++ b/pageserver/src/walredo/process/process_impl/process_async.rs @@ -1,6 +1,9 @@ use self::no_leak_child::NoLeakChild; use crate::{ - config::PageServerConf, metrics::{WalRedoKillCause, WAL_REDO_PROCESS_COUNTERS, WAL_REDO_RECORD_COUNTER}, walrecord::NeonWalRecord, walredo::process::{no_leak_child, protocol} + config::PageServerConf, + metrics::{WalRedoKillCause, WAL_REDO_PROCESS_COUNTERS, WAL_REDO_RECORD_COUNTER}, + walrecord::NeonWalRecord, + walredo::process::{no_leak_child, protocol}, }; use anyhow::Context; use bytes::Bytes; diff --git a/pageserver/src/walredo/process/process_impl/process_std.rs b/pageserver/src/walredo/process/process_impl/process_std.rs index 3e1111642b..db28a60e42 100644 --- a/pageserver/src/walredo/process/process_impl/process_std.rs +++ b/pageserver/src/walredo/process/process_impl/process_std.rs @@ -1,6 +1,9 @@ use self::no_leak_child::NoLeakChild; use crate::{ - config::PageServerConf, metrics::{WalRedoKillCause, WAL_REDO_PROCESS_COUNTERS, WAL_REDO_RECORD_COUNTER}, walrecord::NeonWalRecord, walredo::process::{no_leak_child, protocol} + config::PageServerConf, + metrics::{WalRedoKillCause, WAL_REDO_PROCESS_COUNTERS, WAL_REDO_RECORD_COUNTER}, + walrecord::NeonWalRecord, + walredo::process::{no_leak_child, protocol}, }; use anyhow::Context; use bytes::Bytes;