Skip to content

feat(raft): implement ReadIndex-based linearizable reads#113

Merged
slow2342 merged 1 commit into
mainfrom
feat/linearizable-readindex
Jun 11, 2026
Merged

feat(raft): implement ReadIndex-based linearizable reads#113
slow2342 merged 1 commit into
mainfrom
feat/linearizable-readindex

Conversation

@slow2342

Copy link
Copy Markdown
Owner

Summary

Replace the simplified leader-check-only linearizable read with the full Raft ReadIndex protocol. The leader now sends a heartbeat to confirm its authority before allowing reads, preventing stale reads during network partitions where a leader has been isolated but hasn't yet discovered a new leader.

Changes

  • src/raft/node.rs — Add ReadIndexRequest type, read-index channel in EventLoopChannels, pending tracking in event loop, and Notify on RaftSharedState for efficient wait signaling.
  • src/raft/handle.rs — Add read_index() and wait_for_apply() to RaftHandle trait. Make ensure_linearizable() async to use the real ReadIndex protocol. Add Clone derive to RaftError. Add 12 unit tests.
  • src/raft/raftrs_handle.rs — Implement read_index() and wait_for_apply() via channel and shared Notify.
  • src/api/kv.rs — Update linearizable_read() to use async ensure_linearizable() and Notify-based waiting instead of 5ms polling. Gate range() on serializable field.
  • src/main.rs — Wire read_index_tx from RaftNodeHandle into RaftRsHandle.
  • proto/kv.proto — Add bool serializable = 7 to RangeRequest, matching GetRequest.

Testing

  • 12 new unit tests covering read_index(), wait_for_apply(), ensure_linearizable() with leader/no-leader/not-leader/channel-closed/redirect scenarios
  • All 102 existing tests pass
  • cargo clippy -- -D warnings and cargo fmt -- --check clean

Related issues

Refs #84

Replace the simplified leader-check-only linearizable read with the full
Raft ReadIndex protocol. The leader now sends a heartbeat to confirm its
authority before allowing reads, preventing stale reads during network
partitions where a leader has been isolated but hasn't yet discovered a
new leader.

Key changes:
- Add ReadIndex channel and request type to the raft event loop
- Process MsgReadIndex via raft-rs read_index() with pending tracking
- Add read_index() and wait_for_apply() to RaftHandle trait
- Replace 5ms polling with Notify-based waiting for applied_index
- Add serializable field to RangeRequest proto (matching GetRequest)
- Add 12 unit tests covering read_index, ensure_linearizable, and redirects
@slow2342
slow2342 merged commit 78e465e into main Jun 11, 2026
6 of 8 checks passed
@slow2342
slow2342 deleted the feat/linearizable-readindex branch June 12, 2026 04:38
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