• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

databendlabs / openraft / 27397846385
87%

Build:
DEFAULT BRANCH: main
Ran 12 Jun 2026 06:07AM UTC
Jobs 1
Files 263
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

12 Jun 2026 05:58AM UTC coverage: 86.622%. First build
27397846385

push

github

drmingdrmer
change: leadership-transfer vote request overrides leader lease

# Summary

A vote request sent by a leadership-transfer election now carries a
`leadership_transfer` flag, and a voter grants it even when its leader
lease has not expired. Previously the transfer relied on the
`TransferLeaderRequest` broadcast disabling the lease on every voter
before the target's vote request arrived; when the vote request overtook
the broadcast, the vote was rejected and, with elections disabled, the
cluster stayed leaderless.

# Details

- The race: `broadcast_transfer_leader()` sends `TransferLeaderRequest`
  to each voter as an independent task, and the target starts its
  election as soon as its own copy arrives. The election's vote request
  can reach another voter before that voter's lease-disabling broadcast
  does; the voter then rejects the vote by the leader-lease check. With
  `enable_elect: false` the candidate never retries, so the cluster
  stays leaderless permanently. Hit by the merge queue under
  `OPENRAFT_NETWORK_SEND_DELAY=30`:
  https://github.com/databendlabs/openraft/actions/runs/27390569655

- The fix is the special flag from the Raft dissertation, section 4.2.3:
  `VoteRequest.leadership_transfer` claims the election is authorized by
  the current Leader, and the voter exempts such a request from the
  lease check. The flag travels with the vote request itself, so it is
  immune to ordering between separate RPC paths. Disabling the lease on
  receiving `TransferLeaderRequest` is kept as a fallback.

- Public API: the new `pub` field on `VoteRequest` is a source-breaking
  change for code that constructs it with a struct literal or matches it
  exhaustively; `VoteRequest::new()` is unchanged. On the wire the field
  deserializes to `false` when absent (`serde(default)`), so requests
  from older peers behave as before. The `raft-kv-memstore-grpc` example
  protobuf carries the new field.

Upgrade tip:

Construct `VoteRequest` with `VoteRequest:... (continued)

20 of 20 new or added lines in 2 files covered. (100.0%)

16505 of 19054 relevant lines covered (86.62%)

145366.28 hits per line

Jobs
ID Job ID Ran Files Coverage
1 27397846385.1 12 Jun 2026 06:07AM UTC 263
86.62
GitHub Action Run
Source Files on build 27397846385
  • Tree
  • List 263
  • Changed 0
  • Source Changed 0
  • Coverage Changed 0
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Repo
  • Github Actions Build #27397846385
  • 1e00adfe on github
  • Prev Build on main (#27361362374)
  • Next Build on main (#27400130554)
  • Delete
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc