Skip to content

Commit 96a390d

Browse files
antiguruclaude
andcommitted
adapter: resolve scoped feature flags, gated, with create-time evaluation
The resolution layer that consumes the durable scoped overrides, behind the `enable_scoped_system_parameters` dyncfg (off by default). * The sync loop evaluates the `cluster` and `replica` LaunchDarkly contexts and records an override only when the scoped value differs from the environment- wide value, comparing in canonical encoding so bool spellings match. The whole evaluation is skipped while the gate is off, and the working copy cleared. * Resolution boundaries: cluster-coherent overrides feed plan-time `OptimizerFeatureOverrides` (with a lenient bool decode so `on`/`off` cannot panic the optimizer); replica-local overrides feed the compute controller's per-replica dyncfg push. * Create-time evaluation resolves a freshly created cluster or replica through a shared `SystemParameterFrontend` so new objects get their overrides without waiting for the next sync tick. * Tests: canonical bool bridging, lenient optimizer decode, frontend context construction, the LaunchDarkly end-to-end cases, and workload-harness registration of the new gate. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 5d24e1f commit 96a390d

21 files changed

Lines changed: 1280 additions & 25 deletions

File tree

misc/python/materialize/mzcompose/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,11 @@ def get_variable_system_parameters(
228228
"true" if version >= MzVersion.parse_mz("v26.18.0-dev") else "false",
229229
["true", "false"],
230230
),
231+
VariableSystemParameter(
232+
"enable_scoped_system_parameters",
233+
"false",
234+
["true", "false"],
235+
),
231236
VariableSystemParameter(
232237
"enable_upsert_v2",
233238
"false",

misc/python/materialize/parallel_workload/action.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1518,6 +1518,7 @@ def __init__(
15181518
)
15191519
self.flags_with_values["enable_eager_delta_joins"] = BOOLEAN_FLAG_VALUES
15201520
self.flags_with_values["enable_public_metrics_endpoint"] = BOOLEAN_FLAG_VALUES
1521+
self.flags_with_values["enable_scoped_system_parameters"] = BOOLEAN_FLAG_VALUES
15211522
self.flags_with_values["persist_batch_structured_key_lower_len"] = [
15221523
"0",
15231524
"1",

src/adapter-types/src/dyncfgs.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,17 @@ pub const CATALOG_INFO_METRICS_RECONCILE_INTERVAL: Config<Duration> = Config::ne
267267
"How frequently to reconcile the catalog `*_info` metrics with the catalog. A zero duration disables reconciliation.",
268268
);
269269

270+
/// Whether per-cluster and per-replica scoped system parameters are evaluated.
271+
/// Off by default: the parameter sync loop evaluates no cluster/replica
272+
/// contexts and resolution falls back to the environment-wide value everywhere
273+
/// (the pre-scoped behavior). Enabling it (e.g. from LaunchDarkly) turns on
274+
/// scoped evaluation without a deploy.
275+
pub const ENABLE_SCOPED_SYSTEM_PARAMETERS: Config<bool> = Config::new(
276+
"enable_scoped_system_parameters",
277+
false,
278+
"Whether per-cluster and per-replica scoped system parameters are evaluated and applied.",
279+
);
280+
270281
/// Adds the full set of all adapter `Config`s.
271282
pub fn all_dyncfgs(configs: ConfigSet) -> ConfigSet {
272283
configs
@@ -304,4 +315,5 @@ pub fn all_dyncfgs(configs: ConfigSet) -> ConfigSet {
304315
.add(&ARRANGEMENT_SIZE_HISTORY_COLLECTION_INTERVAL)
305316
.add(&ARRANGEMENT_SIZE_HISTORY_RETENTION_PERIOD)
306317
.add(&CATALOG_INFO_METRICS_RECONCILE_INTERVAL)
318+
.add(&ENABLE_SCOPED_SYSTEM_PARAMETERS)
307319
}

src/adapter/src/client.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ use crate::command::{
5656
CatalogDump, CatalogSnapshot, Command, CopyFromStdinWriter, ExecuteResponse, Response,
5757
SASLChallengeResponse, SASLVerifyProofResponse, SuperuserAttribute,
5858
};
59+
use crate::config::{ScopedParameters, SystemParameterFrontend};
5960
use crate::coord::{Coordinator, ExecuteContextGuard};
6061
use crate::error::AdapterError;
6162
use crate::metrics::{self, Metrics};
@@ -555,6 +556,31 @@ Issue a SQL query to get started. Need help?
555556
rx.await.expect("coordinator unexpectedly gone")
556557
}
557558

559+
/// Returns a snapshot of the catalog.
560+
pub async fn catalog_snapshot(&self) -> Arc<Catalog> {
561+
let (tx, rx) = oneshot::channel();
562+
self.send(Command::CatalogSnapshot { tx });
563+
let CatalogSnapshot { catalog } = rx.await.expect("coordinator unexpectedly gone");
564+
catalog
565+
}
566+
567+
/// Replaces the scoped feature-flag overrides (the complete desired state).
568+
/// Used by the system-parameter sync loop to reconcile the coordinator's
569+
/// scoped-parameter working copy from continuous LaunchDarkly evaluation.
570+
pub async fn update_scoped_system_parameters(&self, overrides: ScopedParameters) {
571+
let (tx, rx) = oneshot::channel();
572+
self.send(Command::UpdateScopedSystemParameters { overrides, tx });
573+
let _ = rx.await;
574+
}
575+
576+
/// Installs (or replaces) the shared system-parameter frontend on the
577+
/// coordinator, letting the create-cluster / create-replica paths resolve a
578+
/// new object's scoped overrides synchronously. Sent by the sync loop each
579+
/// time it (re)initializes the frontend. Fire-and-forget.
580+
pub fn install_scoped_system_parameter_frontend(&self, frontend: Arc<SystemParameterFrontend>) {
581+
self.send(Command::InstallScopedSystemParameterFrontend { frontend });
582+
}
583+
558584
#[instrument(level = "debug")]
559585
pub(crate) fn send(&self, cmd: Command) {
560586
self.inner_cmd_tx
@@ -1320,6 +1346,8 @@ impl SessionClient {
13201346
| Command::PrivilegedCancelRequest { .. }
13211347
| Command::GetSystemVars { .. }
13221348
| Command::SetSystemVars { .. }
1349+
| Command::UpdateScopedSystemParameters { .. }
1350+
| Command::InstallScopedSystemParameterFrontend { .. }
13231351
| Command::Terminate { .. }
13241352
| Command::RetireExecute { .. }
13251353
| Command::CheckConsistency { .. }

src/adapter/src/command.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ use tokio::sync::{mpsc, oneshot};
4646
use uuid::Uuid;
4747

4848
use crate::catalog::Catalog;
49+
use crate::config::{ScopedParameters, SystemParameterFrontend};
4950
use crate::coord::appends::BuiltinTableAppendNotify;
5051
use crate::coord::consistency::CoordinatorInconsistencies;
5152
use crate::coord::peek::{PeekDataflowPlan, PeekResponseUnary};
@@ -168,6 +169,27 @@ pub enum Command {
168169
tx: oneshot::Sender<Result<(), AdapterError>>,
169170
},
170171

172+
/// Replace the scoped feature-flag overrides (the complete desired state).
173+
/// Computed by the system-parameter sync loop from continuous LaunchDarkly
174+
/// evaluation. The coordinator stores this working copy and reconciles it
175+
/// into the per-scope resolution boundaries (the compute controller's
176+
/// per-replica dyncfg layer for `replica`-scoped parameters). See the
177+
/// scoped feature flags design.
178+
UpdateScopedSystemParameters {
179+
overrides: ScopedParameters,
180+
tx: oneshot::Sender<()>,
181+
},
182+
183+
/// Install (or replace) the shared system-parameter frontend on the
184+
/// coordinator, so the create-cluster / create-replica paths can resolve a
185+
/// new object's scoped overrides synchronously, before the controller
186+
/// installs it or its first dataflow is planned, rather than waiting for
187+
/// the next sync tick. Sent by the sync loop whenever it (re)initializes the
188+
/// frontend. See the scoped feature flags design.
189+
InstallScopedSystemParameterFrontend {
190+
frontend: Arc<SystemParameterFrontend>,
191+
},
192+
171193
InjectAuditEvents {
172194
events: Vec<crate::catalog::InjectedAuditEvent>,
173195
conn_id: ConnectionId,
@@ -369,6 +391,8 @@ impl Command {
369391
| Command::Terminate { .. }
370392
| Command::GetSystemVars { .. }
371393
| Command::SetSystemVars { .. }
394+
| Command::UpdateScopedSystemParameters { .. }
395+
| Command::InstallScopedSystemParameterFrontend { .. }
372396
| Command::RetireExecute { .. }
373397
| Command::CheckConsistency { .. }
374398
| Command::Dump { .. }
@@ -407,6 +431,8 @@ impl Command {
407431
| Command::Terminate { .. }
408432
| Command::GetSystemVars { .. }
409433
| Command::SetSystemVars { .. }
434+
| Command::UpdateScopedSystemParameters { .. }
435+
| Command::InstallScopedSystemParameterFrontend { .. }
410436
| Command::RetireExecute { .. }
411437
| Command::CheckConsistency { .. }
412438
| Command::Dump { .. }

src/adapter/src/config.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,12 @@ mod params;
2525
mod sync;
2626

2727
pub use backend::SystemParameterBackend;
28-
pub use frontend::SystemParameterFrontend;
28+
pub use frontend::{
29+
ClusterEvalContext, ClusterScopeContext, ReplicaEvalContext, ReplicaScopeContext,
30+
SystemParameterFrontend,
31+
};
2932
pub use params::{ModifiedParameter, SynchronizedParameters};
33+
pub(crate) use sync::evaluate_scoped_parameters;
3034
pub use sync::system_parameter_sync;
3135

3236
/// Scoped (per-cluster and per-replica) system-parameter overrides, keyed by

0 commit comments

Comments
 (0)