/** * 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(); } }
/** 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(); } }
/** 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(); } } }
/** * 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!"); }
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; } }
/** * 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); }
/** 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(); }
/** * 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(); }
/** * 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(); }
/** 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."); }