make the default process kind runtime-configurable, and switch to sync

This commit is contained in:
Christian Schwarz
2024-04-03 21:00:06 +02:00
parent cca66e5e82
commit 67a7abc7cf
6 changed files with 70 additions and 7 deletions

View File

@@ -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<MaxVectoredReadBytes>,
validate_vectored_get: BuilderValue<bool>,
walredo_process_kind: BuilderValue<crate::walredo::ProcessKind>,
}
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<PageServerConf> {
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"
);

View File

@@ -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;

View File

@@ -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<u8> 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(),);
}
}

View File

@@ -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;

View File

@@ -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;