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;
}
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);
}
Aggregations