All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jgroups.protocols.tom.SenderManager Maven / Gradle / Ivy

Go to download

This artifact provides a single jar that contains all classes required to use remote EJB and JMS, including all dependencies. It is intended for use by those not using maven, maven users should just import the EJB and JMS BOM's instead (shaded JAR's cause lots of problems with maven, as it is very easy to inadvertently end up with different versions on classes on the class path).

There is a newer version: 33.0.2.Final
Show newest version
package org.jgroups.protocols.tom;

import org.jgroups.Address;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * Keeps track of all sent messages, until the final sequence number is known
 *
 * @author Pedro Ruivo
 * @since 3.1
 */
public class SenderManager {

    public static final long NOT_READY = -1;

    private final ConcurrentMap sentMessages = new ConcurrentHashMap<>();

    /**
     * Add a new message sent
     * @param messageID             the message ID
     * @param destinations          the destination set
     * @param initialSequenceNumber the initial sequence number
     * @param deliverToMyself       true if *this* member is in destination sent, false otherwise
     */
    public void addNewMessageToSend(MessageID messageID, Collection
destinations, long initialSequenceNumber, boolean deliverToMyself) { MessageInfo messageInfo = new MessageInfo(destinations, initialSequenceNumber, deliverToMyself); if (deliverToMyself) { messageInfo.setProposeReceived(messageID.getAddress()); } sentMessages.put(messageID, messageInfo); } /** * Add a propose from a member in destination set * @param messageID the message ID * @param from the originator of the propose * @param sequenceNumber the proposed sequence number * @return NOT_READY if the final sequence number is not know, or the final sequence number */ public long addPropose(MessageID messageID, Address from, long sequenceNumber) { MessageInfo messageInfo = sentMessages.get(messageID); if (messageInfo != null && messageInfo.addPropose(from, sequenceNumber)) { return messageInfo.getAndMarkFinalSent(); } return NOT_READY; } /** * Mark the message as sent * @param messageID the message ID * @return return true if *this* member is in destination set */ public boolean markSent(MessageID messageID) { MessageInfo messageInfo = sentMessages.remove(messageID); return messageInfo != null && messageInfo.toSelfDeliver; } /** * obtains the destination set of a message * @param messageID the message ID * @return the destination set */ public Set
getDestination(MessageID messageID) { MessageInfo messageInfo = sentMessages.get(messageID); Set
destination; if (messageInfo != null) { destination = new HashSet<>(messageInfo.destinations); } else { destination = Collections.emptySet(); } return destination; } /** * removes all pending messages */ public void clear() { sentMessages.clear(); } public Collection getPendingMessageIDs() { return sentMessages.keySet(); } public long removeLeavers(MessageID messageID, Collection
leavers) { MessageInfo messageInfo = sentMessages.get(messageID); if (messageInfo != null && messageInfo.removeLeavers(leavers)) { return messageInfo.getAndMarkFinalSent(); } return NOT_READY; } /** * The state of a message (destination, proposes missing, the highest sequence number proposed, etc...) */ private static class MessageInfo { private ArrayList
destinations; private long highestSequenceNumberReceived; private BitSet receivedPropose; private boolean finalMessageSent = false; private boolean toSelfDeliver = false; private MessageInfo(Collection
addresses, long sequenceNumber, boolean selfDeliver) { this.destinations = new ArrayList<>(addresses); this.highestSequenceNumberReceived = sequenceNumber; createNewBitSet(addresses.size()); this.toSelfDeliver = selfDeliver; } private synchronized boolean addPropose(Address from, long sequenceNumber) { setProposeReceived(from); highestSequenceNumberReceived = Math.max(highestSequenceNumberReceived, sequenceNumber); return checkAllProposesReceived(); } private synchronized long getAndMarkFinalSent() { if (checkAllProposesReceived() && !finalMessageSent) { finalMessageSent = true; return highestSequenceNumberReceived; } return NOT_READY; } private void createNewBitSet(int maxElements) { receivedPropose = new BitSet(maxElements); for (int i = 0; i < maxElements; ++i) { receivedPropose.set(i); } } private void setProposeReceived(Address address) { int idx = destinations.indexOf(address); if (idx == -1) { throw new IllegalStateException("Address doesn't exists in destination list. Address is " + address); } receivedPropose.set(idx, false); } private boolean checkAllProposesReceived() { return receivedPropose.isEmpty(); } public synchronized boolean removeLeavers(Collection
leavers) { for (Address address : leavers) { int idx = destinations.indexOf(address); if (idx == -1) { continue; } receivedPropose.set(idx, false); } return checkAllProposesReceived(); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy