@Override
  protected void execute() {

    if (masterNode.isPresent()) {
      ChordRoutingTable routingTable = (ChordRoutingTable) masterNode.getChordRoutingTable();
      updatePredecessor = routingTable.getNextUpdatePredecessor();

      log.debug(
          "check predecessor node "
              + masterNode
              + " update pred = "
              + updatePredecessor
              + " simTime = "
              + Simulator.getCurrentTime() / Simulator.SECOND_UNIT);

      msg = new RetrievePredecessorMsg(masterNode.getLocalOverlayContact(), updatePredecessor);

      if (updatePredecessor.equals(masterNode.getLocalOverlayContact())) {
        // catch exception that the first host has itself as predecessor
        predOfPredecessor = routingTable.getPredecessor();
        operationFinished(true);
        ((ChordRoutingTable) masterNode.getChordRoutingTable())
            .updateDistantPredecessor(updatePredecessor, predOfPredecessor);
      } else {
        sendRetrievePredecessorMsg();
      }

    } else {
      operationFinished(false);
    }
  }
 public AbstractSkyNetMessage(
     SkyNetNodeInfo senderNodeInfo,
     SkyNetNodeInfo receiverNodeInfo,
     long skyNetMsgID,
     boolean ack,
     boolean receiverSP,
     boolean senderSP) {
   timestamp = Simulator.getCurrentTime();
   this.senderNodeInfo = senderNodeInfo;
   this.receiverNodeInfo = receiverNodeInfo;
   this.skyNetMsgID = skyNetMsgID;
   this.ack = ack;
   this.receiverSP = receiverSP;
   this.senderSP = senderSP;
   this.size =
       Constants.LONG_SIZE
           + (SkyNetConstants.SKY_NET_NODE_INFO_SIZE) * 2
           + Constants.LONG_SIZE
           + 3 * Constants.BOOLEAN_SIZE;
 }