long addRemoteMessageToDeliver(MessageID messageID, Message message, long remoteSequenceNumber, long viewId) { MessageInfo messageInfo; long sequenceNumber; synchronized (deliverySet) { long currentViewId = internalGetViewId(); if (currentViewId != -1 //we have a view, check the view id && viewId <= currentViewId //message from the current or previous view, check the members && !currentView.containsMember(message.getSrc())) { //node no longer in view. discard it return -1; } sequenceNumber = sequenceNumberManager.updateAndGet(remoteSequenceNumber); messageInfo = new MessageInfo(messageID, message, sequenceNumber); deliverySet.add(messageInfo); } messageCache.put(messageID, messageInfo); return sequenceNumber; }
@Override public List<Message> getNextMessagesToDeliver() throws InterruptedException { LinkedList<Message> toDeliver = new LinkedList<>(); synchronized (deliverySet) { while (deliverySet.isEmpty() || !deliverySet.first().isReadyToDeliver()) { deliverySet.wait(); } Iterator<MessageInfo> iterator = deliverySet.iterator(); while (iterator.hasNext()) { MessageInfo messageInfo = iterator.next(); if (messageInfo.isReadyToDeliver()) { toDeliver.add(messageInfo.getMessage()); iterator.remove(); } else { break; } } } return toDeliver; }
@Override public List<Message> getNextMessagesToDeliver() throws InterruptedException { LinkedList<Message> toDeliver = new LinkedList<>(); synchronized (deliverySet) { while (deliverySet.isEmpty() || !deliverySet.first().isReadyToDeliver()) { deliverySet.wait(); } Iterator<MessageInfo> iterator = deliverySet.iterator(); while (iterator.hasNext()) { MessageInfo messageInfo = iterator.next(); if (messageInfo.isReadyToDeliver()) { toDeliver.add(messageInfo.getMessage()); iterator.remove(); } else { break; } } } return toDeliver; }
long addRemoteMessageToDeliver(MessageID messageID, Message message, long remoteSequenceNumber, long viewId) { MessageInfo messageInfo; long sequenceNumber; synchronized (deliverySet) { long currentViewId = internalGetViewId(); if (currentViewId != -1 //we have a view, check the view id && viewId <= currentViewId //message from the current or previous view, check the members && !currentView.containsMember(message.getSrc())) { //node no longer in view. discard it return -1; } sequenceNumber = sequenceNumberManager.updateAndGet(remoteSequenceNumber); messageInfo = new MessageInfo(messageID, message, sequenceNumber); deliverySet.add(messageInfo); } messageCache.put(messageID, messageInfo); return sequenceNumber; }
/** * delivers a message that has only as destination member this node * * @param msg the message */ void deliverSingleDestinationMessage(Message msg, MessageID messageID) { synchronized (deliverySet) { long sequenceNumber = sequenceNumberManager.get(); MessageInfo messageInfo = new MessageInfo(messageID, msg, sequenceNumber); messageInfo.updateAndMarkReadyToDeliver(sequenceNumber); deliverySet.add(messageInfo); notifyIfNeeded(); } }
@GuardedBy("deliverySet") private void notifyIfNeeded() { if (!deliverySet.isEmpty() && deliverySet.first().isReadyToDeliver()) { deliverySet.notify(); } }
/** * @return {@code true} if the member who sent the message left the cluster and the message isn't ready to be deliver. */ @GuardedBy("deliverySet") private boolean removeMessage(MessageInfo messageInfo) { if (currentView.containsMember(messageInfo.getMessage().getSrc()) || messageInfo.isReadyToDeliver()) { return false; } else { messageCache.remove(messageInfo.messageID); return true; } }
long addLocalMessageToDeliver(MessageID messageID, Message message, ToaHeader header) { MessageInfo messageInfo; long sequenceNumber; synchronized (deliverySet) { sequenceNumber = sequenceNumberManager.getAndIncrement(); messageInfo = new MessageInfo(messageID, message, sequenceNumber); deliverySet.add(messageInfo); } header.setSequencerNumber(sequenceNumber); messageCache.put(messageID, messageInfo); return sequenceNumber; }
/** * @return {@code true} if the member who sent the message left the cluster and the message isn't ready to be deliver. */ @GuardedBy("deliverySet") private boolean removeMessage(MessageInfo messageInfo) { if (currentView.containsMember(messageInfo.getMessage().getSrc()) || messageInfo.isReadyToDeliver()) { return false; } else { messageCache.remove(messageInfo.messageID); return true; } }
long addLocalMessageToDeliver(MessageID messageID, Message message, ToaHeader header) { MessageInfo messageInfo; long sequenceNumber; synchronized (deliverySet) { sequenceNumber = sequenceNumberManager.getAndIncrement(); messageInfo = new MessageInfo(messageID, message, sequenceNumber); deliverySet.add(messageInfo); } header.setSequencerNumber(sequenceNumber); messageCache.put(messageID, messageInfo); return sequenceNumber; }
/** * delivers a message that has only as destination member this node * * @param msg the message */ void deliverSingleDestinationMessage(Message msg, MessageID messageID) { synchronized (deliverySet) { long sequenceNumber = sequenceNumberManager.get(); MessageInfo messageInfo = new MessageInfo(messageID, msg, sequenceNumber); messageInfo.updateAndMarkReadyToDeliver(sequenceNumber); deliverySet.add(messageInfo); notifyIfNeeded(); } }
@GuardedBy("deliverySet") private void notifyIfNeeded() { if (!deliverySet.isEmpty() && deliverySet.first().isReadyToDeliver()) { deliverySet.notify(); } }