Search in sources :

Example 6 with RemoteQueueBinding

use of org.apache.activemq.artemis.core.server.cluster.RemoteQueueBinding in project activemq-artemis by apache.

the class BindingsImpl method getNextBinding.

/**
 * This code has a race on the assigned value to routing names.
 * <p>
 * This is not that much of an issue because<br>
 * Say you have the same queue name bound into two servers. The routing will load balance between
 * these two servers. This will eventually send more messages to one server than the other
 * (depending if you are using multi-thread), and not lose messages.
 */
private Binding getNextBinding(final Message message, final SimpleString routingName, final List<Binding> bindings) {
    Integer ipos = routingNamePositions.get(routingName);
    int pos = ipos != null ? ipos : 0;
    int length = bindings.size();
    int startPos = pos;
    Binding theBinding = null;
    int lastLowPriorityBinding = -1;
    while (true) {
        Binding binding;
        try {
            binding = bindings.get(pos);
        } catch (IndexOutOfBoundsException e) {
            // This can occur if binding is removed while in route
            if (!bindings.isEmpty()) {
                pos = 0;
                startPos = 0;
                length = bindings.size();
                continue;
            } else {
                break;
            }
        }
        Filter filter = binding.getFilter();
        if (filter == null || filter.match(message)) {
            // unnecessary overhead)
            if (length == 1 || (binding.isConnected() && (messageLoadBalancingType.equals(MessageLoadBalancingType.STRICT) || binding.isHighAcceptPriority(message)))) {
                theBinding = binding;
                pos = incrementPos(pos, length);
                break;
            } else {
                // the localQueue should always have the priority over the secondary bindings
                if (lastLowPriorityBinding == -1 || messageLoadBalancingType.equals(MessageLoadBalancingType.ON_DEMAND) && binding instanceof LocalQueueBinding) {
                    lastLowPriorityBinding = pos;
                }
            }
        }
        pos = incrementPos(pos, length);
        if (pos == startPos) {
            // if no bindings were found, we will apply a secondary level on the routing logic
            if (lastLowPriorityBinding != -1) {
                try {
                    theBinding = bindings.get(lastLowPriorityBinding);
                } catch (IndexOutOfBoundsException e) {
                    // This can occur if binding is removed while in route
                    if (!bindings.isEmpty()) {
                        pos = 0;
                        lastLowPriorityBinding = -1;
                        continue;
                    } else {
                        break;
                    }
                }
                pos = incrementPos(lastLowPriorityBinding, length);
            }
            break;
        }
    }
    if (pos != startPos) {
        routingNamePositions.put(routingName, pos);
    }
    if (messageLoadBalancingType.equals(MessageLoadBalancingType.OFF) && theBinding instanceof RemoteQueueBinding) {
        theBinding = getNextBinding(message, routingName, bindings);
    }
    return theBinding;
}
Also used : Binding(org.apache.activemq.artemis.core.postoffice.Binding) RemoteQueueBinding(org.apache.activemq.artemis.core.server.cluster.RemoteQueueBinding) Filter(org.apache.activemq.artemis.core.filter.Filter) RemoteQueueBinding(org.apache.activemq.artemis.core.server.cluster.RemoteQueueBinding)

Example 7 with RemoteQueueBinding

use of org.apache.activemq.artemis.core.server.cluster.RemoteQueueBinding in project activemq-artemis by apache.

the class MessageRedistributionTest method closeConsumerAndConnectionConcurrently.

private void closeConsumerAndConnectionConcurrently(int targetNode, int remoteNode) throws Exception {
    String targetUri = getServerUri(targetNode);
    System.out.println("uri is " + targetUri);
    ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(targetUri);
    Connection conn = null;
    CountDownLatch active = new CountDownLatch(1);
    try {
        conn = factory.createConnection();
        conn.start();
        Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
        Destination dest = ActiveMQDestination.createDestination("queue0", ActiveMQDestination.QUEUE_TYPE);
        ConsumerThread consumer = new ConsumerThread(session, dest);
        consumer.setMessageCount(0);
        consumer.setFinished(active);
        consumer.start();
        assertTrue("consumer takes too long to finish!", active.await(5, TimeUnit.SECONDS));
    } finally {
        conn.close();
    }
    Wait.waitFor(() -> getRemoteQueueBinding(servers[remoteNode]) != null);
    // check remote server's consumer count
    RemoteQueueBinding remoteBinding = getRemoteQueueBinding(servers[remoteNode]);
    assertNotNull(remoteBinding);
    Wait.waitFor(() -> remoteBinding.consumerCount() >= 0);
    int count = remoteBinding.consumerCount();
    assertTrue("consumer count should never be negative " + count, count >= 0);
}
Also used : ActiveMQConnectionFactory(org.apache.activemq.ActiveMQConnectionFactory) ActiveMQDestination(org.apache.activemq.command.ActiveMQDestination) Destination(javax.jms.Destination) ConsumerThread(org.apache.activemq.util.ConsumerThread) Connection(javax.jms.Connection) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) CountDownLatch(java.util.concurrent.CountDownLatch) Session(javax.jms.Session) RemoteQueueBinding(org.apache.activemq.artemis.core.server.cluster.RemoteQueueBinding)

Aggregations

RemoteQueueBinding (org.apache.activemq.artemis.core.server.cluster.RemoteQueueBinding)7 SimpleString (org.apache.activemq.artemis.api.core.SimpleString)6 Binding (org.apache.activemq.artemis.core.postoffice.Binding)6 Bindings (org.apache.activemq.artemis.core.postoffice.Bindings)3 LocalQueueBinding (org.apache.activemq.artemis.core.postoffice.impl.LocalQueueBinding)3 Map (java.util.Map)2 PostOffice (org.apache.activemq.artemis.core.postoffice.PostOffice)2 QueueBinding (org.apache.activemq.artemis.core.postoffice.QueueBinding)2 ActiveMQServer (org.apache.activemq.artemis.core.server.ActiveMQServer)2 PrintWriter (java.io.PrintWriter)1 StringWriter (java.io.StringWriter)1 ByteBuffer (java.nio.ByteBuffer)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 List (java.util.List)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 ConcurrentMap (java.util.concurrent.ConcurrentMap)1 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 Connection (javax.jms.Connection)1