Skip to content

design: two-runtime compute for read isolation + shared arrangements#37747

Draft
antiguru wants to merge 6 commits into
mainfrom
claude/two-runtime-compute-design
Draft

design: two-runtime compute for read isolation + shared arrangements#37747
antiguru wants to merge 6 commits into
mainfrom
claude/two-runtime-compute-design

Conversation

@antiguru

Copy link
Copy Markdown
Member

Motivation

A compute replica maintains indexes/MVs and serves reads on the same timely worker threads, so an index peek's cursor walk waits behind maintenance work (large merges, joins) and read tail latency tracks maintenance load. This is design-only: two design packages describing how to isolate reads from maintenance, and the differential primitive that enables it.

No code. The implementation prerequisite (moving arrangement batches from Rc to Arc) is a separate change: differential TimelyDataflow/differential-dataflow#807 and materialize #37743.

Description

Two design packages under doc/developer/design/, each a README.md (the design) plus a background.md (grounded status-quo baseline, so the design reads as a delta):

  • 20260720_two_runtime_compute/ — the compute-layer design. Full arc in two stages:
    • Stage 1: offload fast-path index peek reads off the worker thread to a reader pool (the pattern Persist peeks already use), needing only Arc batches + a Send snapshot. No second runtime.
    • Stage 2: a second "query" timely runtime in the same process that imports maintenance arrangements to serve slow-path peeks and ad-hoc query dataflows, so query rendering never competes with maintenance for threads.
    • Covers compaction reconciliation (controller stays the authority), controller transparency, the single-instance process-global assumptions, and thread allocation.
  • 20260719_shared_arrangements_across_runtimes/ — the differential-level primitive (Arc-backed spines + a sharing module) the compute design consumes, plus its own status-quo background.

background.md in each is grounded in file:line references to the current tree.

Verification

Design docs only. No code, no tests. Correctness arguments are in the docs; the primitive's implementation is exercised by tests in #807.

🤖 Generated with Claude Code


Generated by Claude Code

claude added 2 commits July 20, 2026 14:02
The differential-level primitive design (README.md) plus a status-quo
background (background.md) describing how a single-runtime arrangement works
today. Moved out of the Arc-migration implementation branch so design review
is separate from the code change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwFQJa3HSy8oGJZ3X9uGZx
New design package for splitting a compute replica's maintenance work from its
read serving. README.md covers the full arc in two stages: stage 1 offloads
fast-path index peek reads off the worker thread (no second runtime, needs only
Arc batches + a Send snapshot), stage 2 stands up a second query timely runtime
that imports maintenance arrangements for slow-path peeks and ad-hoc query
dataflows. background.md grounds it in how a compute replica is structured
today. Cross-linked with the shared-arrangements primitive design, which this
design consumes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwFQJa3HSy8oGJZ3X9uGZx
claude added 4 commits July 20, 2026 14:29
Lock in the direction: the split stays internal to compute behind one protocol
endpoint, with a routing layer dispatching by target id (peeks and temporary
dataflows to the interactive runtime, indexes/MVs/subscribes to the maintenance
runtime). The interactive runtime never pins maintenance compaction, it tracks
maintenance's since or holds nothing, so the controller stays the sole
compaction authority and no interactive lease can wedge maintenance. Equal
worker counts are a categorical requirement so cross-runtime exchange never
arises. Rename the read-serving runtime to the interactive runtime throughout.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwFQJa3HSy8oGJZ3X9uGZx
Equal worker counts are settled, with core sharing between the 2N threads left
to later measurement. The two runtimes share fate like the replica process does
today: a fatal error in either restarts the whole replica, with no partial
failure and no cross-runtime read fallback. Retire the corresponding open
questions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwFQJa3HSy8oGJZ3X9uGZx
Collapse the worker-mediated stage 1 into a single architecture: the interactive
runtime serves all reads from threads that hold the published arrangement
directly, so a read's latency floor is CPU contention with maintenance, not
waiting for a maintenance worker to return to its loop. Correct the framing that
adversarial review flagged: the walk itself is not made faster (a point-lookup
stays microseconds), it is moved off the maintenance critical path; the snapshot
memory cost is transient and bounded, not a new doubling, since fueled merges
already hold input and output together.

State the compaction and Send work as required primitive changes rather than
done facts: the publisher must not pin compaction (today it freezes it at
publish-time since), reads must register no independent hold, and snapshot_at
must enforce the since gate. Call out the new components honestly: the
process-level multiplexer (not a PartitionedComputeState reuse), the publication
registry with a block-until-published handshake, the interactive read path, the
equal-peers assertion, and the cancellation and batches_through hazards. Fix the
background note that described the spines as Arc-backed on main.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwFQJa3HSy8oGJZ3X9uGZx
…ek mode

Revert the snapshot-only conclusion. A frozen snapshot cannot serve a subscribe,
which needs the ongoing change stream, so a snapshot-only primitive would
foreclose ever moving subscribes to the interactive runtime. Keep the general
model: import an arrangement with an as_of and replay its change stream, with a
real read hold released on drop. Peeks use a pin-free snapshot mode of the same
shared trace, dataflows and future subscribes use the import mode.

Reframe the compaction story accordingly. The two defects adversarial review
found are (1) publishing must carry no independent compaction floor (today the
publisher freezes it at publish-time since) and (2) snapshot_at must enforce the
since gate. An importer holding its own as_of is intended, not a defect: it
matches a stuck read today and is bounded by the controller's hold and shared
fate. Drop the incorrect 'reads register no hold' requirement.

Determine and document the insertion point: a publication point on the arrange
stream at export_index, not an Arc-native TraceBox (which would lock the
maintenance worker's hot path). Per-process registry keyed by GlobalId; two
interactive read entry points (snapshot peek, import dataflow). Add a
corrections note to the primitive design so the two docs agree.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwFQJa3HSy8oGJZ3X9uGZx
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.

2 participants