bitflicker64 commented on code in PR #3185:
URL: https://github.com/apache/hugegraph/pull/3185#discussion_r3943251810


##########
hugegraph-pd/hg-pd-core/src/main/java/org/apache/hugegraph/pd/raft/RaftEngine.java:
##########
@@ -203,7 +204,94 @@ public void shutDown() {
     }
 
     public boolean isLeader() {
-        return this.raftNode.isLeader(true);
+        Node node = this.raftNode;
+        return node != null && node.isLeader(true);
+    }
+
+    /**
+     * Whether this node currently sees a raft leader.
+     * <p>
+     * A follower only keeps its leader while heartbeats keep arriving inside 
the election
+     * timeout, and a leader only keeps its role while it can reach a quorum. 
Seeing a leader
+     * therefore means this node is part of a quorum from its own point of 
view, which is the
+     * signal a readiness probe needs. Served from the state machine 
callbacks, not from the
+     * raft node, so it never waits on the node lock.
+     */
+    public boolean hasLeader() {
+        return this.raftNode != null && this.stateMachine.seesLeader();
+    }
+
+    /**
+     * Take a view of the local raft state from the volatile copies the state 
machine
+     * callbacks maintain, never from the raft node itself. During an election 
jraft holds
+     * the node lock while it reconnects to peers, so a probe that read the 
node stalled for
+     * the connect timeout instead of answering its 503 promptly. All fields 
derive from the
+     * same callback-written values, so they cannot contradict each other.
+     * <p>
+     * The state reported is the last one a callback announced: leader, 
follower, error or
+     * shutdown. jraft emits no callback for candidacy or leadership transfer, 
so a candidate
+     * reads as a follower that sees no leader, which yields the same 
not-ready answer.
+     */
+    public RaftStatus getRaftStatus() {
+        if (this.raftNode == null) {
+            return new RaftStatus(false, State.STATE_UNINITIALIZED.name(), 
false);
+        }
+        State state = this.stateMachine.getProbeState();
+        return new RaftStatus(state.isActive() && 
this.stateMachine.seesLeader(),

Review Comment:
   Fixed in b6ad26c with the requested single-snapshot shape. 
`RaftStateMachine` now holds one immutable `ProbeView` of state plus leader 
visibility, written once per callback on the FSM thread (`onStopFollowing` 
carries the previous state forward, so an error state is not masked), and 
`getRaftStatus()` and `hasLeader()` read the field once. Fair point that this 
is the a3b9395 reincarnation of the overpromise 7074440 closed. The javadoc 
also now says the view trails the node by whatever sits in the FSM queue, 
rather than implying it is current. 9/9 readiness tests on JDK 11.



##########
hugegraph-pd/docs/api-reference.md:
##########
@@ -774,6 +774,54 @@ curl http://localhost:8620/actuator/health
 }
 ```
 
+### Liveness and Readiness
+
+Two unauthenticated endpoints are meant for probes and startup gates:
+
+| Endpoint | Meaning | Status |
+|----------|---------|--------|
+| `GET /v1/health` | Liveness: the REST listener is up. Does not consult raft. 
| always `200` |
+| `GET /v1/ready` | Readiness: the raft node is active and sees a leader, so 
this PD is inside a quorum. | `200` when ready, `503` otherwise |
+
+```bash
+curl -i http://localhost:8620/v1/ready
+```
+
+**Response** (leader of a healthy cluster):
+```json
+{
+  "ready": true,
+  "state": "STATE_LEADER",
+  "isLeader": true
+}
+```
+
+A follower reports `"state": "STATE_FOLLOWER"` with `"isLeader": false`. When
+the quorum is lost the PD keeps answering `/v1/health` with `200` but
+`/v1/ready` turns into `503` with `"ready": false`. Being unauthenticated, the
+body carries no cluster addresses; the leader's address stays on `/v1/members`.
+
+The answer is served from state the raft callbacks maintain rather than from
+the raft node, so it stays prompt while an election is running and never waits
+on the node lock. `state` is therefore the last change raft announced: jraft
+emits no callback for candidacy or leadership transfer, so a candidate reports
+`STATE_FOLLOWER` with `"ready": false`.

Review Comment:
   Fixed in b6ad26c. The section now names `STATE_UNINITIALIZED` as what a PD 
reports from process start until its first raft callback, tied to the 
pre-quorum startup window the compose docs describe. I left the `raftNode == 
null` branch returning the same string: by the time the REST listener can 
answer at all, the two cases differ only for the instant between servlet start 
and `RaftEngine.init`, and both mean the same thing to a caller, do not gate on 
this PD yet.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to