Raft::Node exposes add_server (adds as Learner), promote_learner (Learner → Voter), and remove_server, but not demote_voter (Voter → Learner). The mechanism is already in place — Peer has a Role field (Voter | Learner) and append_configuration accepts arbitrary peer lists — only the public entry point is missing.
Use case
In LavinMQ we'd like to tie raft role to ISR membership: when a node falls out of the in-sync replica set, demote it to Learner. raft.cr's election algorithm correctly excludes Learners (they can't be candidates and don't count toward voter quorum), giving a stronger, structurally cleaner version of the "non-ISR node can't lead" safety property than a post-election ISR-membership check.
Proposed solution
Mirror promote_learner: construct an updated peer list where the target peer's role flips from Voter to Learner, then append_configuration it. A short spec for the flip plus a follower being prevented from winning election while demoted should be enough.
Caveat
Doesn't fully close the leader-dies-before-committing-the-demotion gap (an uncommitted demote can be overwritten by a new leader). Narrows the window though, since enforcement is continuous rather than one-shot — an inherent property of raft membership changes, not specific to this API.
Raft::Nodeexposesadd_server(adds as Learner),promote_learner(Learner → Voter), andremove_server, but notdemote_voter(Voter → Learner). The mechanism is already in place —Peerhas aRolefield (Voter | Learner) andappend_configurationaccepts arbitrary peer lists — only the public entry point is missing.Use case
In LavinMQ we'd like to tie raft role to ISR membership: when a node falls out of the in-sync replica set, demote it to Learner. raft.cr's election algorithm correctly excludes Learners (they can't be candidates and don't count toward voter quorum), giving a stronger, structurally cleaner version of the "non-ISR node can't lead" safety property than a post-election ISR-membership check.
Proposed solution
Mirror
promote_learner: construct an updated peer list where the target peer's role flips from Voter to Learner, thenappend_configurationit. A short spec for the flip plus a follower being prevented from winning election while demoted should be enough.Caveat
Doesn't fully close the leader-dies-before-committing-the-demotion gap (an uncommitted demote can be overwritten by a new leader). Narrows the window though, since enforcement is continuous rather than one-shot — an inherent property of raft membership changes, not specific to this API.