예제 #1
0
  /**
   * Deliver a DATA event received from the network.
   *
   * @param event the event received from the network.
   */
  private void reliableDATADeliver(GroupSendableEvent event) {
    Message msg = event.getMessage();
    long[] uniformInfo = new long[vs.view.length];
    for (int i = uniformInfo.length; i > 0; i--) uniformInfo[i - 1] = msg.popLong();
    mergeUniformInfo(uniformInfo);
    DATAHeader header = DATAHeader.pop(event.getMessage());
    log.debug(
        "Received DATA message: "
            + header.id
            + ":"
            + header.sn
            + " timestpamp is "
            + timeProvider.currentTimeMillis());
    header.setTime(delay[header.id] + timeProvider.currentTimeMillis());
    ListContainer container = new ListContainer(event, header);
    // add the event to the RECEIVED list...
    R.addLast(container);
    // ... and set a timer to be delivered later, according to the delay that came with the message
    setTimer(container, delay[header.id], vs.id);

    // Deliver event to the upper layer (spontaneous order)
    try {
      event.go();
    } catch (AppiaEventException e) {
      e.printStackTrace();
    }
  }
예제 #2
0
 /** Sets a timer to delay a message that came from the network. */
 private void setTimer(ListContainer container, long timeout, ViewID vid) {
   try {
     log.debug("TIME Container: " + container.header.getTime());
     SETOTimer timer =
         new SETOTimer(
             timeout / 1000,
             container.event.getChannel(),
             Direction.DOWN,
             this,
             EventQualifier.ON,
             container,
             vid);
     timer.go();
     if (log.isDebugEnabled())
       log.debug(
           "Setting new timer. NOW is "
               + timeProvider.currentTimeMillis()
               + " timer to "
               + timer.getTimeout());
   } catch (AppiaEventException e) {
     e.printStackTrace();
   } catch (AppiaException e) {
     e.printStackTrace();
   }
 }
예제 #3
0
 /** Tries to deliver Uniform messages. */
 private void deliverUniform() {
   log.debug("Trying to deliver FINAL messages!");
   ListIterator it = G.listIterator();
   while (it.hasNext()) {
     ListSEQContainer nextMsg = (ListSEQContainer) it.next();
     if (isUniform(nextMsg.header)) {
       ListContainer msgContainer = getRemoveMessage(nextMsg.header, R);
       log.debug("Resending message to Appl: " + msgContainer.event);
       log.debug(
           "["
               + ls.my_rank
               + "] Delivering final "
               + msgContainer.header.id
               + ":"
               + msgContainer.header.sn
               + " timestamp "
               + timeProvider.currentTimeMillis());
       try {
         // deliver uniform notification
         UniformServiceEvent use =
             new UniformServiceEvent(
                 msgContainer.event.getChannel(),
                 Direction.UP,
                 this,
                 msgContainer.event.getMessage());
         use.go();
       } catch (AppiaEventException e) {
         e.printStackTrace();
       }
       it.remove();
     }
   }
 }
예제 #4
0
 /**
  * Received a message delayed by a timer.
  *
  * @param timer
  */
 private void handleTimer(SETOTimer timer) {
   if (timer.vid.equals(vs.id)) {
     long now = timeProvider.currentTimeMillis();
     log.debug(ls.my_rank + ": received timer on " + now);
     deliverOptimistic(timer.container);
   } else log.debug(ls.my_rank + ": received SETOTimer from a previous view... discarding!");
 }
예제 #5
0
 private void handleUniformTimer(UniformTimer timer) {
   // log.debug("Uniform timer expired. Now is: "+timeProvider.currentTimeMillis());
   if (!isBlocked
       && newUniformInfo
       && timeProvider.currentTimeMillis() - timeLastMsgSent >= UNIFORM_INFO_PERIOD) {
     // log.debug("Last message sent was at time "+timeLastMsgSent+". Will send Uniform info!");
     sendUniformInfo(timer.getChannel());
     newUniformInfo = false;
   }
 }
예제 #6
0
 /**
  * Received Sequencer message
  *
  * @param message
  */
 private void handleSequencerMessage(SeqOrderEvent message) {
   log.debug(
       "Received SEQ message from "
           + message.orig
           + " timestamp is "
           + timeProvider.currentTimeMillis());
   if (message.getDir() == Direction.DOWN)
     log.error("Wrong direction (DOWN) in event " + message.getClass().getName());
   else reliableSEQDeliver(message);
 }
예제 #7
0
 /** Deliver a SEQUENCER message received from the network. */
 private void reliableSEQDeliver(SeqOrderEvent event) {
   Message msg = event.getMessage();
   long[] uniformInfo = new long[vs.view.length];
   for (int i = uniformInfo.length; i > 0; i--) uniformInfo[i - 1] = msg.popLong();
   mergeUniformInfo(uniformInfo);
   SEQHeader header = SEQHeader.pop(event.getMessage());
   log.debug(
       "["
           + ls.my_rank
           + "] Received SEQ message "
           + header.id
           + ":"
           + header.sn
           + " timestamp is "
           + timeProvider.currentTimeMillis());
   lastOrderList[ls.my_rank] = header.order;
   newUniformInfo = true;
   // add it to the sequencer list
   S.add(new ListSEQContainer(header, timeProvider.currentTimeMillis()));
   log.debug("Received SEQ from " + event.orig + " at time " + timeProvider.currentTimeMillis());
   // and tries to deliver messages that already have the order
   deliverRegular();
   deliverUniform();
 }
예제 #8
0
 /**
  * In a view change, if there are messages that were not delivered, deliver them in a
  * deterministic order. This can be done because VSync ensures that when a new View arrives, all
  * members have the same set of messages.
  */
 private void dumpPendingMessages() {
   ListContainer container = null;
   nextDeterministicCounter = 0;
   while ((container = getNextDeterministic()) != null) {
     if (log.isDebugEnabled()) {
       log.debug("Message in deterministic order with SN=" + (localSN + 1) + " -> " + container);
     }
     SEQHeader header =
         new SEQHeader(
             container.header.sender(), container.header.sn(), ++lastOrderList[ls.my_rank]);
     lastOrderList[ls.my_rank] = header.order;
     S.add(new ListSEQContainer(header, timeProvider.currentTimeMillis()));
     log.debug("Resending message to Appl: " + container.event);
     // getRemoveMessage(container.header,R);
   }
   deliverRegular();
 }
예제 #9
0
 /**
  * Multicast a DATA event to the group.
  *
  * @param event the event to be multicast.
  * @param msgDelay the message delay associated with the event.
  */
 private void reliableDATAMulticast(GroupSendableEvent event, long msgDelay) {
   DATAHeader header = new DATAHeader(ls.my_rank, sendingLocalSN++, msgDelay);
   DATAHeader.push(header, event.getMessage());
   Message msg = event.getMessage();
   for (int i = 0; i < lastOrderList.length; i++) msg.pushLong(lastOrderList[i]);
   log.debug(
       "Sending DATA message from appl. Rank="
           + ls.my_rank
           + " SN="
           + sendingLocalSN
           + " Delay="
           + msgDelay);
   try {
     event.go();
   } catch (AppiaEventException e) {
     e.printStackTrace();
   }
   timeLastMsgSent = timeProvider.currentTimeMillis();
 }
예제 #10
0
  /** Tries to deliver REGULAR message. */
  private void deliverRegular() {
    for (ListIterator li = S.listIterator(); li.hasNext(); ) {
      ListSEQContainer orderedMsg = (ListSEQContainer) li.next();
      if (log.isDebugEnabled()) {
        log.debug("Message in order with SN=" + (localSN + 1) + " -> " + orderedMsg);
        log.debug("Messages in S {");
        listOrderedMessage();
        log.debug("}");
      }

      ListContainer msgContainer = getMessage(orderedMsg.header, R);

      if (msgContainer != null && !hasMessage(orderedMsg, G)) {
        log.debug(
            "["
                + ls.my_rank
                + "] Delivering regular "
                + msgContainer.header.id
                + ":"
                + msgContainer.header.sn
                + " timestamp "
                + timeProvider.currentTimeMillis());
        try {
          RegularServiceEvent rse =
              new RegularServiceEvent(
                  msgContainer.event.getChannel(),
                  Direction.UP,
                  this,
                  msgContainer.event.getMessage());
          rse.go();
        } catch (AppiaEventException e1) {
          e1.printStackTrace();
        }
        G.addLast(orderedMsg);

        // Avoid delivery of optimistic service after the regular service
        if (O.contains(msgContainer)) O.remove(msgContainer);
        else O.add(msgContainer);

        if (pendingView == null) {
          // ADJUSTING DELAYS
          log.debug(ls.my_rank + ": Adjusting delays...");
          long _final = orderedMsg.time;
          long _fast = msgContainer.header.getTime();
          int _sender = msgContainer.header.id;
          if (lastsender != -1) {
            log.debug("continueing adjusting the delays!");
            log.debug(
                "_final:"
                    + _final
                    + " | lastfinal:"
                    + lastfinal
                    + " | _fast:"
                    + _fast
                    + " | lastfast:"
                    + lastfast);
            long delta = (_final - lastfinal) - (_fast - lastfast);
            log.debug("DELTA: " + delta);
            if (delta > 0) {
              log.debug("adjust(" + lastsender + "," + _sender + "," + delta + ")");
              adjust(lastsender, _sender, delta);
            } else if (delta < 0) {
              log.debug("adjust(" + _sender + "," + lastsender + "," + delta + ")");
              adjust(_sender, lastsender, -delta);
            }
          }
          lastsender = _sender;
          lastfast = _fast;
          lastfinal = _final;
          localSN++;
        }
      }
      li.remove();
    }
    log.debug("DeliverRegular finished.");
  }