Skip to content

Fix ClusterMembership API: Separate static role from dynamic leader info #201

@JoshuaChi

Description

@JoshuaChi

Problem

After Phase 2 optimization (atomic leader_id), integration tests fail because get_cluster_metadata() RPC cannot report current leader.

Root Cause: NodeMeta.role field conflates two concepts:

  • Static configuration role (Voter vs Learner) - immutable cluster config
  • Dynamic runtime role (Leader vs Follower) - changes with elections

When we removed mark_leader_id() for performance optimization, Membership no longer updates NodeMeta.role, causing ClientManager to fail finding leader.

Solution

Follow best practices - separate static config from dynamic state:

Proto Change:

message ClusterMembership {
    uint64 version = 1;
    repeated NodeMeta nodes = 2;
    optional uint32 current_leader_id = 3;  // NEW: dynamic leader info
}

message NodeMeta {
    uint32 id = 1;
    string address = 2;
    int32 role = 3;        // ONLY static role (Voter=1, Learner=2)
    NodeStatus status = 4;
}

Implementation:

  • NodeMeta.role: Static configuration (from initial_cluster)
  • ClusterMembership.current_leader_id: Read from shared_state.current_leader()
  • All roles attach current_leader_id when handling RaftEvent::ClusterConf

Benefits

  • ✅ Clean API semantics: static vs dynamic separation
  • ✅ No dual maintenance of leader info
  • ✅ Preserves Phase 2 performance gains (atomic hot-path)

Metadata

Metadata

Assignees

No one assigned

    Labels

    raft-membershipDynamic membership changes (node addition/removal from cluster)

    Type

    Projects

    Status

    Done

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions