release(v0.7.0): Replication GA for multi-shard masters#333
Conversation
Real Redis-compatible async replication with WAIT/ACK semantics: a multi-shard master (--shards N) streams a merged, exactly-once command feed to a single-shard streaming replica across all six data planes — KV, vector/text index, graph, WS, MQ, and temporal. Every write plane is crash-durable and survives kill -9 on either side. Folds in the full v0.6.1 hardening scope (WAL v3 storage-kernel M1–M4) and a supply-chain CI gate (cargo audit + cargo deny). Gate: 24h replication kill-9 soak (REPL-SOAK-01) PASSED, zero acked-write loss — SOAK-PASS duration=86400s cycles=114 acked=82044 inflight=7 master_kills=57 replica_kills=57 (2026-07-15, RC e2d8789, run dir moon-soak/runs/20260714-141946). Version bump 0.6.0 -> 0.7.0 (Cargo.toml + Cargo.lock), CHANGELOG [0.7.0] roll-up with the #71a replica-TTL disclosure, RELEASES.md entry, PRODUCTION-CONTRACT REPL-SOAK-01 + SUPPLY-01 ticked, shardslice-migration waiver retired (cross-shard read now tracked as open GA gap XSHARD-READ-01, not time-boxed). Known limitation: streaming replica is single-shard only (--shards 1); multi-shard replicas roadmapped for v0.8/v0.9. Closes #62, #65. Discloses #71a (replica TTL semantics; absolute-rewrite in v0.7.1 / #71b). author: Tin Dang <tindang.ht97@gmail.com>
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
|
Warning Review limit reached
Next review available in: 42 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. 📝 WalkthroughWalkthroughThe release is bumped to 0.7.0, with updated release records and replication documentation covering topology, durability, failover, monitoring, and TTL semantics. Production-contract entries record completed supply-chain and replication-soak gates. Changes0.7.0 replication GA release
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@CHANGELOG.md`:
- Around line 22-25: Update CHANGELOG.md lines 22-25 to describe REPL-SOAK-01 as
completed/manual evidence, unless the release workflow is changed to enforce it
for v0.7.0. Update docs/PRODUCTION-CONTRACT.md line 129 to remove the claim that
this evidence gates the v0.7.0 tag unless such enforcement is added.
In `@RELEASES.md`:
- Around line 3-5: Synchronize the production-contract ledger with the v0.7.0
release entry: update the XSHARD-READ-01/shardslice-migration status in the
ledger so it no longer shows an active August 1, 2026 waiver and instead matches
the release’s retired-waiver, open-GA-gap state.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 796d3f38-5f10-40be-8798-654952e9e22a
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (4)
CHANGELOG.mdCargo.tomlRELEASES.mddocs/PRODUCTION-CONTRACT.md
| Soak evidence (release gate REPL-SOAK-01): `SOAK-PASS duration=86400s cycles=114 | ||
| acked=82044 inflight=7 master_kills=57 replica_kills=57` — 82,044 WAIT-acked writes | ||
| preserved across 114 alternating kill-9 cycles, zero acked-write loss (2026-07-15, | ||
| run dir `moon-soak/runs/20260714-141946`, RC `e2d87893`). |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
The soak is documented as a tag gate, but the supplied release workflow does not enforce it for v0.7.0.
CHANGELOG.md#L22-L25: either wire REPL-SOAK-01 into an enforcing release step or describe it as completed/manual evidence.docs/PRODUCTION-CONTRACT.md#L129-L129: remove the claim that the row gates the v0.7.0 tag unless the workflow is changed to block that tag.
📍 Affects 2 files
CHANGELOG.md#L22-L25(this comment)docs/PRODUCTION-CONTRACT.md#L129-L129
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@CHANGELOG.md` around lines 22 - 25, Update CHANGELOG.md lines 22-25 to
describe REPL-SOAK-01 as completed/manual evidence, unless the release workflow
is changed to enforce it for v0.7.0. Update docs/PRODUCTION-CONTRACT.md line 129
to remove the claim that this evidence gates the v0.7.0 tag unless such
enforcement is added.
| ## v0.7.0 — 2026-07-15 | ||
| milestones: v0.7.0 "Replication GA for multi-shard masters" (soak-gated tag; v0.6.1 hardening folded in) | ||
| waivers: none — the v0.6.0 `shardslice-migration` waiver (was: expires 2026-08-01) is **retired**; lock-free cross-shard read work is now tracked as an open GA gap (`XSHARD-READ-01`, ROADMAP R4), not a time-boxed waiver. |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Synchronize the waiver status with the production-contract ledger.
This release entry says the shardslice-migration waiver is retired, but docs/PRODUCTION-CONTRACT.md Line 132 still says it expires on August 1, 2026 and remains unstarted. Update one ledger so both documents consistently represent whether XSHARD-READ-01 is a retired waiver or an active open obligation.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@RELEASES.md` around lines 3 - 5, Synchronize the production-contract ledger
with the v0.7.0 release entry: update the XSHARD-READ-01/shardslice-migration
status in the ledger so it no longer shows an active August 1, 2026 waiver and
instead matches the release’s retired-waiver, open-GA-gap state.
…clustering walkthrough A "Replication GA" release shipped without replication coverage in the config/tuning reference docs, and the clustering guide's replica walkthrough had rotted: - guides/clustering.md showed the PRE-GA topology (single-shard leader, multi-shard replica) — the reverse of the shipped v0.7 shape (multi-shard master, --shards 1 replica) — directly contradicting its own info box. Corrected the walkthrough. - Its "WS.*/MQ.* not replicated yet" note was stale: Wave B (task #34) replicates all six planes (KV, vector/text, graph, WS, MQ, temporal). Corrected. - Added: WAIT-durability ladder, replica promotion (REPLICAOF NO ONE), INFO replication monitoring (offset/lag, master_link_status), replica-TTL caveat (#71a). New "Replication" section in docs/configuration.md (topology + durability flags + REPLICAOF-is-runtime-only) and "Replication durability" section in guides/tuning.md (RPO/latency ladder, read-scaling with more replicas, lag alerting). Cross-linked. All facts verified against the code (handshake.rs INFO fields, apply.rs Wave B WS/MQ arms, metadata.rs command table). Docs-only; ships in the v0.7.0 tag. Refs #65. author: Tin Dang <tindang.ht97@gmail.com>
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/guides/clustering.md`:
- Around line 80-83: Update the clustering guide’s SET/WAIT example to execute
both commands on the same persistent or interactive redis-cli connection,
preserving the explanation that WAIT must observe writes from its current
connection.
- Around line 107-114: Update the “Replica TTL semantics (v0.7)” warning to
state that relative-TTL expiry on replicas can shift بسبب replication/apply
delay because the countdown starts when the command is applied, even with
synchronized clocks; retain clock skew as an additional source of offset.
- Around line 62-64: Update the clustering guide’s replica synchronization
description to identify the full-resync payload as Moon-specific RRDSHARD, not a
standard Redis-format RDB. Remove any implication of interoperability with
heterogeneous Redis replicas, and limit compatibility claims to the PSYNC2
control protocol while preserving the read-only and live-stream behavior.
- Around line 50-54: Align zero-RPO documentation around durable replica
acknowledgements: update the replica startup example in
docs/guides/clustering.md (lines 50-54) to include --appendfsync always; revise
the durability table in docs/configuration.md (lines 67-72) to configure both
master and replica; and update the zero-RPO row in docs/guides/tuning.md (lines
166-170) to require durable replica configuration rather than implying WAIT
alone is sufficient.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 68b354c8-39fa-4de6-9965-6a2a19b31986
📒 Files selected for processing (4)
CHANGELOG.mddocs/configuration.mddocs/guides/clustering.mddocs/guides/tuning.md
🚧 Files skipped from review as they are similar to previous changes (1)
- CHANGELOG.md
| The replica performs a full resync (one merged Redis-format RDB across all planes), | ||
| then applies the live stream. Replicas are **read-only**: writes return | ||
| `-READONLY` (`INFO replication` reports `slave_read_only:1`). |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Do not imply standard Redis replica interoperability.
The supplied architecture contract describes the full-resync payload as RRDSHARD and says conversion to standard Redis RDB for heterogeneous Redis replicas is out of scope. Describe the Moon-specific payload and limit the compatibility claim to the PSYNC2 control protocol.
Also applies to: 100-103
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/guides/clustering.md` around lines 62 - 64, Update the clustering
guide’s replica synchronization description to identify the full-resync payload
as Moon-specific RRDSHARD, not a standard Redis-format RDB. Remove any
implication of interoperability with heterogeneous Redis replicas, and limit
compatibility claims to the PSYNC2 control protocol while preserving the
read-only and live-stream behavior.
…roxy) Moon ships no read/write-splitting proxy: each node is a single server and a v0.7 replica is read-only (writes → -READONLY). Document how to serve one logical endpoint anyway — client-side split (with per-library replica-read option names: lettuce ReadFrom.REPLICA_PREFERRED, redis-py, ioredis scaleReads, go-redis ReadOnly) and a command-aware external RESP proxy (Envoy redis_proxy) — plus the key caveats: a plain L4 LB can't split by command, writes must stay on the master for WAIT durability, and reads must re-point on promotion/failover. Refs #65. author: Tin Dang <tindang.ht97@gmail.com>
…rift accuracy Review of the v0.7.0 replication docs surfaced four accuracy issues; three fixed, one skipped as contradicting the code. - WAIT example (clustering guide): the SET and WAIT ran as two separate `redis-cli` invocations, i.e. two connections. WAIT only counts ACKs for writes issued on its OWN connection, so as written it would observe no pending write. Rewritten to a single interactive session (heredoc). - Zero-RPO durability (clustering + configuration + tuning): a replica ACKs a write when it APPLIES it, not when it fsyncs — so a replica running `everysec`/`no` can satisfy WAIT and still lose the write on its own crash. True zero-RPO needs `--appendfsync always` on BOTH nodes. Added the replica fsync to the startup example, a replica row to the configuration table, and a replica column + note to the tuning RPO ladder. This aligns the docs with the guide's own "appendfsync always on both sides" statement. - Replica TTL drift (clustering warning): relative-TTL expiry on a replica shifts primarily because the countdown starts at APPLY time, so replication/apply delay moves the expiry moment even with perfectly synced clocks. Reworded to lead with apply delay; clock skew retained as an additional offset. Skipped: a suggestion to rename the full-resync payload to a Moon-specific "RRDSHARD" format. The payload is a genuine merged Redis-format RDB (`write_rdb_merged`, master.rs:281/451/483) with Moon's extra planes carried as RDB AUX fields — there is no RRDSHARD format, so the rename would introduce a false claim. author: Tin Dang <tindang.ht97@gmail.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/guides/clustering.md`:
- Around line 121-130: Update the “Client-side (recommended, no extra hop)”
section to explicitly warn that asynchronous replication can make an immediate
replica GET return stale or missing data after a master SET. Instruct callers to
route read-after-write and session-critical reads to the master, or use a
replica catch-up mechanism when replica reads are required.
- Around line 132-135: Qualify the client examples in docs/guides/clustering.md
at lines 132-135, 140-143, and 145-147: keep standalone master/replica examples
separate, and move RedisCluster(read_from_replicas=True), ioredis scaleReads,
go-redis ClusterOptions read routing, and Envoy redis_proxy read policies under
the Redis Cluster section or replace them with standalone equivalents. Update
the failover note to state that REPLICAOF NO ONE still requires topology-aware
client rerouting or an external coordinator; health checks alone do not repoint
clients.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 601c10c7-0c6f-453d-8b33-2dcb76e44b85
📒 Files selected for processing (4)
CHANGELOG.mddocs/configuration.mddocs/guides/clustering.mddocs/guides/tuning.md
🚧 Files skipped from review as they are similar to previous changes (3)
- docs/configuration.md
- docs/guides/tuning.md
- CHANGELOG.md
…andalone vs cluster Second review pass on the read/write-splitting subsection; both findings valid. - Read-after-write staleness (finding 1): the client-side example did a master SET immediately followed by a replica GET of the same key — the exact eventually-consistent race — with no caveat. Added a warning admonition: async replication means a replica read right after a master write can return a stale value or a miss; route read-after-write and session-critical reads to the master, staleness-tolerant reads to replicas, and gate read-your-writes on a WAIT + slave_repl_offset catch-up check. - Standalone vs Cluster conflation (finding 2): the client bullets cited Cluster-only routing constructs (redis-py RedisCluster(read_from_replicas), ioredis scaleReads, go-redis ClusterOptions) inside the STANDALONE master/replica section. Replaced them with standalone equivalents (separate master/replica clients; lettuce MasterReplica) and moved the cluster-client modes into an explicit "Cluster mode only" note. - Failover note: clarified that REPLICAOF NO ONE does not notify clients and health checks alone only detect liveness (not which node is the new master), so repointing needs Moon's Cluster mode or an external orchestrator (k8s/systemd). Explicitly stated Moon does not implement Sentinel — matches the documented non-goal in redis-compat.md / PRODUCTION-CONTRACT.md / ROADMAP.md (do NOT reference Sentinel as a Moon coordinator). author: Tin Dang <tindang.ht97@gmail.com>
v0.7.0 — Replication GA for multi-shard masters
Release commit: version bump + CHANGELOG roll-up + RELEASES.md + contract ticks. No source changes — rides on the soaked RC
e2d87893(functionally identical binary; only the crate version string differs).Release gate — PASSED
24h replication kill-9 soak (
REPL-SOAK-01), zero acked-write loss:82,044 WAIT-acked writes preserved across 114 alternating master/replica
kill -9cycles. Run dirmoon-soak/runs/20260714-141946, RCe2d87893, 2026-07-15.What ships
Real Redis-compatible async replication with WAIT/ACK across all six data planes (KV, vector/text, graph, WS, MQ, temporal); multi-shard master → single-shard streaming replica; every plane crash-durable under
kill -9. Folds in the full v0.6.1 hardening scope (WAL v3 storage-kernel M1–M4) and a supply-chain CI gate (cargo audit+cargo deny).Diff
Cargo.toml/Cargo.lock:0.6.0→0.7.0CHANGELOG.md:[Unreleased]→[0.7.0] — 2026-07-15with headline + #71a replica-TTL disclosureRELEASES.md: v0.7.0 entry with soak evidence;shardslice-migrationwaiver retired (cross-shard read now tracked as open GA gapXSHARD-READ-01, not time-boxed)docs/PRODUCTION-CONTRACT.md:REPL-SOAK-01✅,SUPPLY-01✅Known limitation (disclosed in tag)
Streaming replica is single-shard only (
--shards 1); multi-shard replicas roadmapped for v0.8/v0.9. Relative-TTL commands replicate verbatim (noPEXPIREATrewrite) + role-agnostic active expiry — absolute-rewrite lands in v0.7.1 (#71b).Closes #62, #65. Discloses #71a.
Summary by CodeRabbit
New Features
Documentation
REPLICAOF <host> <port>(no startup flag), including resync/verification (INFO replication,master_link_status), manual failover (REPLICAOF NO ONE), and read/write splitting guidance.WAIT) and clarified replica TTL limitations and monitoring.Chores