Skip to content

feat(wal): overlap bounded replication with local persistence - #469

Merged
beinan merged 1 commit into
mainfrom
codex/wal-early-peer-dispatch
Oct 22, 2026
Merged

beinan merged 1 commit into
mainfrom
codex/wal-early-peer-dispatch

Conversation

@beinan

@beinan beinan commented Oct 22, 2026

Copy link
Copy Markdown
Collaborator

Summary

The runtime currently waits for the leader's complete synchronous storage poll before sending replication packets, delaying the start of follower persistence. Add the default-off runtime.pipeline_replication option to dispatch ordinary, non-snapshot Raft Ready.messages through the existing bounded transport before local persistence.

Follower persistence-required responses, all existing sync barriers, client completions, quorum reads, snapshots, and public synchronous Node::poll() semantics retain their ordering. Packets move shared payload buffers and retain node-wide byte/request credits; a full queue drops for Raft retransmission without blocking the owner. An early packet followed by failed leader persistence remains an uncertain attempt and never a successful ACK from that poll.

This is an experimental option, with no established throughput improvement. It does not make storage asynchronous or allow the Raft owner to tick during a blocking filesystem operation.

Part of #378.

Testing

  • Full repository CI helper: workspace formatting, Clippy and tests; Python tests, Ruff and Pyright. All passed on this source.
  • All-feature/all-target WAL Clippy and tests: 161 library tests passed, 3 ignored; binary and integration suites passed.
  • Block the actual leader sync gate: a follower durably accepts an append while the leader remains blocked, without a client ACK. Assert payload pointer identity, bounded outgoing credits, injected leader/follower sync failures, shared-engine fencing, complete recovery and exact-index retry after reopening all original directories.
  • Snapshot catch-up and restart with both option values.
  • Independent release executables: 192 MiB acknowledged but unpublished; SIGKILL all nine WAL processes; reopen original directories; a missing preparer cannot partially publish; kill the completed preparer to discard its cache; restore both and verify all 64 original 3 MiB rows and columns, aggregate count, version, read-only and negative checks, without producer replay. This is retained-disk process recovery, not volume-loss or throughput evidence.

A cloud comparison using identical binaries and changing only the node option is queued; no result is claimed here. Final-head CI must pass before merge.

@beinan
beinan force-pushed the codex/wal-early-peer-dispatch branch from e37a9b5 to d7b5094 Compare October 22, 2026 11:37
@beinan
beinan merged commit e25c937 into main Oct 22, 2026
14 checks passed
beinan added a commit that referenced this pull request Oct 22, 2026
When an uncompressed engine block misses the read cache, the decoder
currently copies the newly read block into another allocation before
parsing entries. Reuse the original allocation after verifying the
complete block checksum, removing one block-sized allocation and copy.
Compressed decoding, cache isolation, entry parsing, durable ACKs, and
file formats retain their existing behavior.

Refs #378. Built on merged #469.

Validation: actual-file cache and rewrite regressions;
compressed/uncompressed multi-entry reopen; corruption rejection and
recovery after restoring the original byte; log/checkpoint/snapshot
tests; all-feature WAL checks; full local `ci-pr-helper` checks. The
candidate release also passes nine-process WAL crash/reopen and complete
Arrow/Lance recovery with a missing preparer and lost preparation cache.
Local allocation diagnostics confirm the removed allocation; no
end-to-end throughput improvement is claimed.
beinan added a commit that referenced this pull request Oct 22, 2026
A bounded source scan can encounter only records from other tables. The
worker previously released its claim and discarded the scan cursor, then
started from the same durable checkpoint on its next claim. A table
behind more than one scan budget of retained foreign records could
remain unpublished indefinitely.

Retain the empty-page scan hints per fixed worker assignment and move
them through claim jobs. Hints are checked against the complete table
binding, contain only quorum-observed ranges without that table's
records, and never advance durable checkpoints. Scan limits, claim
rotation and publisher fencing remain unchanged. Restart may rescan
those ranges safely.

Refs #378. Built on merged #466, #468, #469, #470 and #471.

Validation:
- Real three-replica WAL, etcd and Lance regression: a target behind 129
retained foreign records fails with the old worker and publishes its
exact payload with the fix, while another table remains unpublished.
- Materializer, worker, service and service/http-client feature Clippy
checks; ingestion and etcd-backed worker recovery suites.
- Full repository CI helper, including Rust/Python tests, formatting and
lint/type checks.

The first worker-suite run encountered an existing lease-revoke timeout
with slow local etcd synchronization. The unchanged suite passed on a
fresh run with the same storage and deadlines; the original failure was
retained. This change fixes publication progress and does not claim a
throughput improvement.
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.

1 participant