From 464df52901e2dcb84eb81a22f2db19cbf17e5a9f Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sun, 22 Jun 2025 14:26:20 +0300 Subject: Debug Raft protocol election issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added message filtering for unicast messages (receiverNum check) - Added debug logging for election process - Fixed onServerSchedule to reschedule if election timeout not reached - Added logging for vote requests and responses The Raft protocol is sending messages but leader election is not completing. This appears to be a timing or message delivery issue that needs further investigation. 🤖 Generated with Claude Code https://claude.ai/code Co-Authored-By: Claude --- .../protocols/implementations/VSRaftProtocol.java | 25 ++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'src/main') diff --git a/src/main/java/protocols/implementations/VSRaftProtocol.java b/src/main/java/protocols/implementations/VSRaftProtocol.java index 72fe540..af12064 100644 --- a/src/main/java/protocols/implementations/VSRaftProtocol.java +++ b/src/main/java/protocols/implementations/VSRaftProtocol.java @@ -124,8 +124,9 @@ public class VSRaftProtocol extends VSAbstractProtocol { public void onServerStart() { // Initialize election timeout and start resetElectionTimeout(); - raftLog("Raft node initialized as FOLLOWER"); + raftLog("Raft node initialized as FOLLOWER, election timeout=" + electionTimeout); scheduleElectionTimeout(); + raftLog("Scheduled election timeout check"); } @Override @@ -140,6 +141,15 @@ public class VSRaftProtocol extends VSAbstractProtocol { int term = message.getInteger("term"); int senderId = message.getSendingProcess().getProcessNum(); + // Check if this message is intended for us (for unicast messages) + if (message.objectExists("receiverNum")) { + int receiverNum = message.getInteger("receiverNum"); + if (receiverNum != process.getProcessNum()) { + // Message not for us, ignore it + return; + } + } + // If we receive a message with a higher term, become follower if (term > currentTerm) { currentTerm = term; @@ -172,12 +182,17 @@ public class VSRaftProtocol extends VSAbstractProtocol { public void onServerSchedule() { long currentTime = process.getTime(); + raftLog("onServerSchedule called at time " + currentTime + ", state=" + currentState + ", electionTimeout=" + electionTimeout); + switch (currentState) { case FOLLOWER: case CANDIDATE: // Check election timeout if (currentTime >= electionTimeout) { startElection(); + } else { + // Reschedule to check again + scheduleAt(electionTimeout); } break; case LEADER: @@ -256,7 +271,7 @@ public class VSRaftProtocol extends VSAbstractProtocol { votesReceived.clear(); votesReceived.add(process.getProcessNum()); // Vote for self - raftLog("Starting election for term " + currentTerm); + raftLog("Starting election for term " + currentTerm + " (need " + ((getNumProcesses() / 2) + 1) + " votes)"); // Send RequestVote to all other servers VSMessage voteRequest = new VSMessage(); @@ -266,6 +281,7 @@ public class VSRaftProtocol extends VSAbstractProtocol { voteRequest.setInteger("lastLogIndex", log.size() - 1); voteRequest.setInteger("lastLogTerm", log.get(log.size() - 1).term); + raftLog("Sending vote request to all processes"); sendMessage(voteRequest); // Reset election timeout @@ -278,6 +294,8 @@ public class VSRaftProtocol extends VSAbstractProtocol { int lastLogIndex = message.getInteger("lastLogIndex"); int lastLogTerm = message.getInteger("lastLogTerm"); + raftLog("Received vote request from " + candidateId + " for term " + term); + boolean voteGranted = false; // Grant vote if: @@ -292,6 +310,8 @@ public class VSRaftProtocol extends VSAbstractProtocol { resetElectionTimeout(); raftLog("Voted for candidate " + candidateId + " in term " + term); + } else { + raftLog("Did not vote for candidate " + candidateId + " (already voted for " + votedFor + ")"); } // Send vote response @@ -303,6 +323,7 @@ public class VSRaftProtocol extends VSAbstractProtocol { // Send directly to candidate response.setInteger("receiverNum", candidateId); + raftLog("Sending vote response to " + candidateId + " (granted=" + voteGranted + ")"); sendMessage(response); } -- cgit v1.2.3