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");
  }