1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// Copyright 2015 The etcd Authors
// Copyright 2026 Leo Cheng
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

///|
/// Whether a quorum of the configuration has been heard from within the current
/// liveness window — the leader itself plus every follower whose progress is
/// flagged active. This is what confirms the leader still commands the cluster,
/// underpinning both check-quorum and lease reads.
pub fn RaftNode::quorum_active(self : RaftNode) -> Bool {
  let acked : Array[String] = [self.id]
  for peer, p in self.progress {
    // The leader itself is always counted (added above); skip its own tracked
    // entry so it is not counted twice now that it appears in the progress map.
    if peer == self.id {
      continue
    }
    if p.is_active() {
      acked.push(peer)
    }
  }
  self.config.has_majority(acked)
}

///|
/// Start a fresh liveness window: forget who has answered so the next window
/// measures only recent contact.
fn RaftNode::reset_recent_active(self : RaftNode) -> Unit {
  for _peer, p in self.progress {
    p.reset_active()
  }
}

///|
/// Serve a linearizable read (Raft §6.4). A follower cannot answer, so `None` is
/// returned. A leader may answer only once it has committed an entry in its own
/// term — the no-op appended on election, once committed, guarantees its commit
/// index reflects the latest term — and only while a quorum has confirmed its
/// leadership this window. The returned index is the commit index the caller
/// must wait for the state machine to reach before replying to the client, which
/// is what makes the read see every previously-acknowledged write.
pub fn RaftNode::read_index(self : RaftNode) -> UInt64? {
  if self.core.role() != Leader {
    return None
  }
  if self.core.term_at(self.core.commit_index) != self.core.current_term() {
    return None
  }
  if self.peers.is_empty() || self.quorum_active() {
    Some(self.core.commit_index)
  } else {
    None
  }
}

///|
/// Whether this leader currently holds a valid lease — a quorum has confirmed it
/// this window — and may therefore serve reads without a fresh round trip.
pub fn RaftNode::has_lease(self : RaftNode) -> Bool {
  self.core.role() == Leader && (self.peers.is_empty() || self.quorum_active())
}