@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);
    }
  }
  private void checkResponsibility(
      SkyNetID ownID, SkyNetID skyNetCoKey, BigDecimal left, BigDecimal right, int iter) {
    skyNetNode.getSkyNetNodeInfo().setCoordinatorKey(skyNetCoKey);
    log.info(
        " The client "
            + skyNetNode.getSkyNetNodeInfo().toString()
            + " is responsible for the CoordinatorKey "
            + skyNetCoKey.getPlainSkyNetID()
            + " in the interval["
            + left.toPlainString()
            + ";"
            + right.toPlainString()
            + "] @ level "
            + iter);

    ISkyNetMonitor monitor = (ISkyNetMonitor) Simulator.getMonitor();
    ChurnStatisticsAnalyzer csAnalyzer =
        (ChurnStatisticsAnalyzer) monitor.getConnectivityAnalyzer(ChurnStatisticsAnalyzer.class);

    if (iter > 0) {
      // complete the parentSkyNetNode Info
      if (isRoot) {
        log.warn(SkyNetUtilities.getTimeAndNetID(skyNetNode) + "lost the root-position");
        csAnalyzer.lostRootPosition(skyNetNode);
        skyNetNode.getMetricUpdateStrategy().setLastMetricSync(0);
      }
      skyNetNode.getSkyNetNodeInfo().setLevel(iter);
      isRoot = false;
      lookupParentCoordinator();
    } else {
      if (!isRoot) {
        log.warn(SkyNetUtilities.getTimeAndNetID(skyNetNode) + "got the root-position");
        csAnalyzer.gotRootPosition(skyNetNode);
        skyNetNode.getMetricUpdateStrategy().setLastMetricSync(0);
      }
      skyNetNode.getSkyNetNodeInfo().setLevel(iter);

      // Also set the observed level at this point
      skyNetNode.getSkyNetNodeInfo().setObservedLevelFromRoot(0);

      isRoot = true;
      skyNetNode.getAttributeUpdateStrategy().resetOnlyAttributeUpdateStrategy();
      skyNetNode.getMetricUpdateStrategy().sendNextDataUpdate();
    }
  }
 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;
 }