public static void handleGetDecision(Message msg) throws Exception { System.out.println("Starting to handle GET_DECISION message"); LogRecord log = ThreePhaseCommitUtility.fetchRecordForTransaction(processId, msg.getTransactionId()); Message decision = new Message(); decision.setMessage(log.getMessage()); decision.setProcessId(processId); decision.setTransactionId(log.getTransactionId()); decision.setPlaylistCommand(log.getPlayListCommand()); if (COMMIT.equals(decision.getMessage()) || ABORT.equals(decision.getMessage())) { netController.sendMsg(msg.getProcessId(), ThreePhaseCommitUtility.serializeMessage(decision)); System.out.println( "Process " + processId + " has sent a response to a GET_DECISION " + decision); } }
public static void participantTerminationProtocol() throws Exception { System.out.println("Process " + processId + " is initiating participant termination protocol"); List<String> receivedMsgs = new ArrayList<String>(); boolean notCommitted = true; System.out.println("Process " + processId + " is waiting for STATE_REQ"); while (notCommitted && processId != coordinatorId) { Timer timer = new Timer(PARTICIPANT_TIME_OUT_IN_SECONDS); timer.start(); while (receivedMsgs.isEmpty() && !timer.hasTimedOut()) { receivedMsgs.addAll(netController.getReceivedMsgs()); } // if time-out has happened if (timer.hasTimedOut() && (participant_waiting_for.equals(STATE_RESP))) { System.out.println( "Process " + processId + " has timed out while waiting for response from co-ordinator"); initiateElection(); if (coordinatorId == processId) { // invoke co-ordinator's termination protocol List<Integer> participants = new ArrayList<Integer>(activeProcesses); System.out.println("active processes!" + activeProcesses); participants.remove((Object) new Integer(processId)); coordinatorTerminationProtocol(participants); } } for (String message : receivedMsgs) { Message msg = ThreePhaseCommitUtility.deserializeMessage(message); if (msg.getProcessId() == coordinatorId && msg.getMessage().equals(STATE_REQ)) { Message state = new Message(); state.setProcessId(processId); state.setTransactionId(msg.getTransactionId()); System.out.println("msg of process " + processId + " is " + msg); if (my_current_state.equals(ABORTED)) { state.setMessage(ABORTED); } else if (my_current_state.equals(COMMIT)) { state.setMessage(COMMITTED); } else if (my_current_state.equals(PRE_COMMIT)) { state.setMessage(COMMITTABLE); } else { state.setMessage(UNCERTAIN); } netController.sendMsg(coordinatorId, ThreePhaseCommitUtility.serializeMessage(state)); participant_waiting_for = STATE_RESP; System.out.println( "Process " + processId + " sends its current state " + state.getMessage()); } else if (msg.getProcessId() == coordinatorId && msg.getMessage().equals(ABORT)) { LogRecord myState = ThreePhaseCommitUtility.fetchRecordForTransaction(processId, msg.getTransactionId()); if (!myState.getMessage().equals(ABORT)) ThreePhaseCommitUtility.writeMessageToDTLog( processId, new LogRecord(msg.getTransactionId(), ABORT, msg.getPlaylistCommand())); System.out.println( "Process " + processId + " received abort during the termination protocol"); participant_waiting_for = ""; notCommitted = false; my_current_state = ABORTED; } else if (msg.getProcessId() == coordinatorId && msg.getMessage().equals(COMMIT)) { LogRecord myState = ThreePhaseCommitUtility.fetchRecordForTransaction(processId, msg.getTransactionId()); if (!myState.getMessage().equals(COMMIT)) { ThreePhaseCommitUtility.writeMessageToDTLog( processId, new LogRecord(msg.getTransactionId(), COMMIT, msg.getPlaylistCommand())); executeCommand(msg.getPlaylistCommand()); } participant_waiting_for = ""; my_current_state = COMMIT; System.out.println( "Process " + processId + " received commit during the termination protocol"); notCommitted = false; } else if (msg.getMessage().equals(GET_DECISION)) { System.out.println( "Process " + processId + " got a GET_DECISION from process " + msg.getProcessId()); handleGetDecision(msg); } else if (msg.getMessage().equals(PRE_COMMIT)) { my_current_state = PRE_COMMIT; Message ack = new Message(); ack.setProcessId(processId); ack.setMessage(ACK); netController.sendMsg(coordinatorId, ThreePhaseCommitUtility.serializeMessage(ack)); System.out.println( "Process " + processId + " received pre_commit during the termination protocol and has sent ACK"); } } receivedMsgs.clear(); } System.out.println("Process " + processId + " has completed participant termination protocol"); }