Skip to content

compute: turn the interactive runtime on in test configurations - #38393

Draft
antiguru wants to merge 1 commit into
mh/interactive-07-reconcile-barrierfrom
mh/interactive-08-enable
Draft

antiguru wants to merge 1 commit into
mh/interactive-07-reconcile-barrierfrom
mh/interactive-08-enable

Conversation

@antiguru

@antiguru antiguru commented Aug 21, 2026 •

Copy link
Copy Markdown
Member

10 of 14 in the interactive-runtime stack. Stacks on #40558, followed by #38676. Tracked by CPU-216. The design document is doc/developer/design/20261107_interactive_runtime.md in #40559.

enable_compute_interactive_runtime moves out of UNINTERESTING_SYSTEM_PARAMETERS, where #38391 parked it, and becomes a variable system parameter defaulting to on. That is what makes every preceding piece reachable: sqllogictest, testdrive, and the mzcompose suites provision replicas with two runtimes. Parallel-workload's FlipFlagsAction is unpinned to both values. Production keeps the dyncfg's own default, off.

Four clusterd-test-driver specs join the two-runtime workflow #40558 added, which runs every spec with one and two workers, so the registry's per-worker pairing is exercised rather than assumed: an index read, a query dataflow scheduled before the index it imports has produced anything, a read through an index that re-exports another's arrangement under a publication point of its own, and a query dataflow over such a re-export. create-dataflow takes a single-read flag, which sets until one past the as_of and the class to OneShotRead, as the adapter does.

divergent-dataflow-cancellation.td keeps the flag off, because its INSERT's read would render on the interactive runtime, whose work is not yet visible in introspection (CPU-222).

read_at_max_timestamp.slt covers reads at Timestamp::MAX, the one read whose until is empty, so the adapter leaves its dataflow a maintained one, which the maintenance runtime renders. Such a read is answerable only against a collection that has sealed, since no finite upper passes MAX, so the file reads off constant-backed indexes, whose dataflows have no inputs and drop their capability after emitting once. Both shapes are covered: a fast-path index peek, served by the interactive runtime over shared indexes, and a join that cannot take the fast path and so builds a dataflow. The reads double as the assertion that those indexes sealed, since a peek finding a live frontier would never return.

With this PR, ReadIsolationUnderHydration (#38542) measures peek latency on a two-runtime replica while hydration saturates the maintenance workers.

A reviewer should check that the test suites need no expectation changes beyond the two files above.

Posted by Claude Code.

🤖 Generated with Claude Code

@antiguru
antiguru force-pushed the mh/interactive-08-enable branch 2 times, most recently from 7cc7c1e to edb0ed3 Compare August 21, 2026 11:50
@antiguru
antiguru force-pushed the mh/interactive-08-enable branch from edb0ed3 to 33f6773 Compare August 21, 2026 12:28
@antiguru
antiguru force-pushed the mh/interactive-08-enable branch from 33f6773 to 2f0fd74 Compare August 21, 2026 13:24
@antiguru
antiguru force-pushed the mh/interactive-08-enable branch from 2f0fd74 to 69cfb34 Compare August 21, 2026 13:42
@antiguru
antiguru requested a review from DAlperin August 21, 2026 13:47
@antiguru
antiguru force-pushed the mh/interactive-08-enable branch from 69cfb34 to 51bbf8a Compare August 21, 2026 14:31
pull Bot pushed a commit to Arstman/materialize that referenced this pull request Aug 21, 2026
…nt sharing (MaterializeInc#38396)

Replaces MaterializeInc#37881, whose head branch lives on a fork and so cannot be the
base of a stacked PR in this repository. Same commits, same tree, on an
upstream branch instead. This is the root of the stack MaterializeInc#38386 through
MaterializeInc#38393, which splits MaterializeInc#37770.

### Motivation

Cross-runtime arrangement sharing (the two-runtime read-isolation work,
MaterializeInc#37770) needs batches readable from a thread other than the one
maintaining the trace. Differential's default spines reference-count
batches with `Rc`, which is worker-local.

### Description

Introduce `mz_row_spine::ArcBatch`, a local newtype around `Arc<B>` that
carries differential's batch traits (the orphan rule forbids the blanket
impl on a bare `Arc<B>`), and switch the production spines and their
builders — `RowRowSpine`, `RowValSpine`, `RowSpine`, `ValRowSpine`,
`ColValSpine`, `ColKeySpine` — from `Rc`/`RcBuilder` to
`ArcBatch`/`ArcBuilder`. An `Arc`-backed batch whose contents are `Send
+ Sync` can be read across threads, which `Rc` cannot do. Only the batch
handle becomes atomic; the batch contents are unchanged, so the cost is
a marginally more expensive refcount.

Also adds generic `ArcOrdVal`/`ArcOrdKeySpine` aliases for callers
outside `mz_compute`, adapts batch-size logging
(`log_arrangement_size_inner`) to reach through the newtype to the inner
`Arc`, and switches the storage sink trace to the `Arc`-backed spine.

Builds against released differential-dataflow 0.25 with no fork or
`[patch.crates-io]`.

### Verification

`cargo check --workspace` passes with no `Cargo.lock` churn.
`relations.slt`'s golden is rewritten because the spine type name
appears in operator names.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
@antiguru
antiguru force-pushed the mh/interactive-08-enable branch from 51bbf8a to 4f02fc3 Compare August 21, 2026 17:54
@antiguru
antiguru force-pushed the mh/interactive-08-enable branch from 4f02fc3 to 099cda1 Compare August 28, 2026 14:06
@antiguru
antiguru force-pushed the mh/interactive-08-enable branch from 099cda1 to be74eb0 Compare September 3, 2026 08:49
@linear-code

linear-code Bot commented Sep 3, 2026

Copy link
Copy Markdown

CPU-215

@antiguru
antiguru force-pushed the mh/interactive-08-enable branch from be74eb0 to 4daa449 Compare September 3, 2026 16:22
@antiguru
antiguru force-pushed the mh/interactive-08-enable branch from 4daa449 to ba882e6 Compare September 4, 2026 17:22
@antiguru
antiguru force-pushed the mh/interactive-08-enable branch from ba882e6 to 0d948f9 Compare September 4, 2026 17:39
@antiguru
antiguru force-pushed the mh/interactive-08-enable branch from 0d948f9 to fc3dd5a Compare September 4, 2026 19:37
@antiguru
antiguru force-pushed the mh/interactive-08-enable branch from 6e98212 to 4b255fe Compare September 7, 2026 18:19
@antiguru
antiguru force-pushed the mh/interactive-08-enable branch from 4b255fe to 0141e18 Compare September 7, 2026 18:43
@antiguru
antiguru force-pushed the mh/interactive-08-enable branch from 0141e18 to 4ec2990 Compare September 9, 2026 13:09
@antiguru
antiguru force-pushed the mh/interactive-08-enable branch from 4ec2990 to 03e5a1d Compare September 12, 2026 13:28
@antiguru
antiguru force-pushed the mh/interactive-08-enable branch from 03e5a1d to d18f90c Compare September 16, 2026 19:43
@antiguru
antiguru force-pushed the mh/interactive-08-enable branch from d18f90c to 9e36a27 Compare September 16, 2026 20:57
@antiguru
antiguru force-pushed the mh/interactive-08-enable branch from 9e36a27 to a6ac11d Compare September 17, 2026 01:50
@antiguru
antiguru force-pushed the mh/interactive-08-enable branch from a6ac11d to 199940a Compare September 23, 2026 11:59
@antiguru
antiguru force-pushed the mh/interactive-08-enable branch from 199940a to 5bf74b6 Compare September 23, 2026 14:11
@antiguru
antiguru force-pushed the mh/interactive-08-enable branch from 5bf74b6 to cb60114 Compare September 24, 2026 11:38
@antiguru
antiguru force-pushed the mh/interactive-08-enable branch from cb60114 to ec4c4c9 Compare September 24, 2026 12:59
Comment thread src/clusterd-test-driver/src/script.rs Resolved
Comment thread src/clusterd-test-driver/src/script.rs Resolved
@def-

def- commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

QA LLM Review

1. MEDIUM -- divergent-dataflow-cancellation.td can no longer see the peek dataflow it cancels

test/testdrive/divergent-dataflow-cancellation.td:107

With the flag now on in testdrive, this test's INSERT ... SELECT over a divergent WMR renders its read as a peek dataflow on the interactive runtime. That runtime installs no logging, so the expect-empty introspection queries at the end of the file cannot observe it. If a cancelled peek dataflow were left running on the interactive runtime, its WMR loop would spin forever on the runtime that now serves every peek of the replica, and this test would still pass.

Details

A non-constant INSERT becomes a read-then-write (src/adapter/src/coord/sequencer/inner.rs:2743), whose read goes through sequence_peek (inner.rs:2908). optimize::peek gives that read until = as_of + 1 (src/adapter/src/optimize/peek.rs:318), so the dataflow is transient and single-time. is_peek_dataflow therefore holds, and Multiplexer::send routes the dataflow, its CancelPeek and its drop to interactive (src/compute-client/src/multiplex.rs:170).

initialize_logging returns early on the interactive role (src/compute/src/compute_state.rs:1204), so none of that dataflow's operators, exports, frontiers or arrangements reach mz_introspection. Every query from line 124 onward reads the maintenance runtime's logs, which never contained it. The index, materialized view and SUBSCRIBE cases still render on maintenance and are still covered. Before this PR the flag sat in UNINTERESTING_SYSTEM_PARAMETERS, testdrive ran a single runtime, and the INSERT case was visible.

The interactive runtime also has a drop path of its own that this check would otherwise guard. handle_allow_compaction treats any id missing from collections as a peer's publication and only records a standing hold, never dropping anything (compute_state.rs:1009). Its soft assert passes precisely on the interactive role. So if a peek dataflow's collection ever went missing there, its empty-frontier AllowCompaction would be silently discarded and the dataflow would keep running.

The PR discussion already attributes the missing interactive introspection to CPU-222. Until that lands, two options keep the test honest. One is to pin enable_compute_interactive_runtime = false beside the existing ALTER SYSTEM at the top of the file, before CREATE CLUSTER test, which works because the flag is read at replica provisioning. The other is to assert the INSERT case's teardown through something the interactive runtime does report.

@antiguru

antiguru commented Oct 2, 2026

Copy link
Copy Markdown
Member Author

Re the QA review on divergent-dataflow-cancellation.td: the file now sets enable_compute_interactive_runtime = false before CREATE CLUSTER test, with TODO(CPU-222), so its introspection checks see the INSERT case again. The silent-discard path is gone too. The interactive runtime now knows its peer collections explicitly, and an AllowCompaction for an id that is neither a collection nor a peer soft-asserts on every runtime. Interactive introspection is planned: interactive workers forward their log events to the paired maintenance worker, with interactive operator and dataflow ids offset by 2^63.

Posted by Claude Code

@bosconi bosconi left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The flag flip itself is scoped correctly; two coverage gaps and a CI timeout question inline.

Comment on lines +428 to +432
VariableSystemParameter(
"enable_compute_interactive_runtime",
"true",
["true", "false"],
),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like enable_upsert_chunked_stash above, say why this is on in CI and off in production, and that it only affects newly provisioned replicas.

Suggested change
VariableSystemParameter(
"enable_compute_interactive_runtime",
"true",
["true", "false"],
),
# On by default so CI exercises the interactive runtime, which is off in
# production while it earns trust. Read when a replica is provisioned, so
# only replicas created after the setting lands are affected.
VariableSystemParameter(
"enable_compute_interactive_runtime",
"true",
["true", "false"],
),

# parameter, so unorchestrated clusterds run the same topology as
# controller-provisioned replicas. Old images ignore the env var.
unified_cluster: bool = True,
interactive_compute: bool = False,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unmanaged replicas ignore the flag (clusters.rs#L467-L479), and only test/clusterd-test-driver passes interactive_compute=True, so platform-checks (UseClusterdCompute), test/cluster, test/cluster-isolation, test/replica-isolation and test/bounded-memory stay single-runtime. Please state that scope in the description, and consider opting at least one compute-focused composition in.

Comment on lines +130 to +134
for name in c.workflows:
if name == "default":
continue
with c.test_case(name):
c.workflow(name)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default workflow now adds ten clusterd runs, but the nightly step still has timeout_in_minutes: 20. Has a nightly run on this head confirmed headroom, or should the timeout go up here?

let name = opt_string(args, "name");
let as_of = req_u64(args, "as-of")?;
let optimize = flags.iter().any(|f| f == "optimize");
let single_read = flags.iter().any(|f| f == "single-read");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing asserts single-read parses to true, and the specs would still pass if it were dropped, because the maintenance runtime would serve the same rows. Add a parse check like the optimize one in parses_create_dataflow_with_mir:

        // The `single-read` flag on the directive line is picked up.
        let single_read = parse_command(
            "create-dataflow name=r as-of=0 single-read\n  import index=1001\n  build id=2000\n    Get u1000\n  export index=2001 on=2000 key=[0]",
        )
        .unwrap();
        assert!(matches!(
            single_read,
            Command::CreateDataflow { single_read: true, .. }
        ));

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants