@Deprecated @Override public Queue createQueue(final long persistenceID, final SimpleString address, final SimpleString name, final Filter filter, final PageSubscription subscription, final SimpleString user, final boolean durable, final boolean temporary, final boolean autoCreated) { return new QueueImpl(persistenceID, address, name, filter, subscription, user, durable, temporary, autoCreated, scheduledExecutor, postOffice, null, null, ArtemisExecutor.delegate(executor), null, this); }
@Override public void route(final Message message, final RoutingContext context) throws Exception { if (purgeOnNoConsumers) { context.setReusable(false); if (getConsumerCount() == 0) { return; } } context.addQueue(address, this); }
@Override public void expire(final MessageReference ref, final ServerConsumer consumer) throws Exception { SimpleString messageExpiryAddress = expiryAddressFromMessageAddress(ref); if (messageExpiryAddress == null) { messageExpiryAddress = expiryAddressFromAddressSettings(ref); } if (messageExpiryAddress != null) { if (logger.isTraceEnabled()) { logger.trace("moving expired reference " + ref + " to address = " + messageExpiryAddress + " from queue=" + this.getName()); } move(null, messageExpiryAddress, null, ref, false, AckReason.EXPIRED, consumer); } else { if (logger.isTraceEnabled()) { logger.trace("expiry is null, just acking expired message for reference " + ref + " from queue=" + this.getName()); } acknowledge(ref, AckReason.EXPIRED, consumer); } if (server != null && server.hasBrokerMessagePlugins()) { final SimpleString expiryAddress = messageExpiryAddress; server.callBrokerMessagePlugins(plugin -> plugin.messageExpired(ref, expiryAddress, consumer)); } }
void postRollback(final LinkedList<MessageReference> refs) { //if we have purged then ignore adding the messages back if (purgeOnNoConsumers && getConsumerCount() == 0) { purgeAfterRollback(refs); return; } addHead(refs, false); }
@Override public void actMessage(Transaction tx, MessageReference ref, boolean fromMessageReferences) throws Exception { incDelivering(ref); acknowledge(tx, ref, ackReason, null); if (fromMessageReferences) { refRemoved(ref); } } };
@Override public void addHead(final List<MessageReference> refs, boolean scheduling) { enterCritical(CRITICAL_PATH_ADD_HEAD); synchronized (this) { try { for (MessageReference ref : refs) { addHead(ref, scheduling); } resetAllIterators(); deliverAsync(); } finally { leaveCritical(CRITICAL_PATH_ADD_HEAD); } } }
@Test public void testBusyConsumer() throws Exception { QueueImpl queue = getTemporaryQueue(); FakeConsumer consumer = new FakeConsumer(); consumer.setStatusImmediate(HandleStatus.BUSY); queue.addConsumer(consumer); final int numMessages = 10; List<MessageReference> refs = new ArrayList<>(); for (int i = 0; i < numMessages; i++) { MessageReference ref = generateReference(queue, i); refs.add(ref); queue.addTail(ref); } Assert.assertEquals(10, getMessageCount(queue)); Assert.assertEquals(0, queue.getScheduledCount()); Assert.assertEquals(0, queue.getDeliveringCount()); queue.deliverNow(); Assert.assertEquals(10, getMessageCount(queue)); Assert.assertEquals(0, queue.getScheduledCount()); Assert.assertEquals(0, queue.getDeliveringCount()); Assert.assertTrue(consumer.getReferences().isEmpty()); consumer.setStatusImmediate(HandleStatus.HANDLED); queue.deliverNow(); assertRefListsIdenticalRefs(refs, consumer.getReferences()); Assert.assertEquals(10, getMessageCount(queue)); Assert.assertEquals(0, queue.getScheduledCount()); Assert.assertEquals(10, queue.getDeliveringCount()); }
queue.addTail(ref); Assert.assertEquals(0, queue.getScheduledCount()); Assert.assertEquals(0, queue.getDeliveringCount()); queue.addConsumer(cons1); queue.deliverNow(); Assert.assertEquals(0, queue.getScheduledCount()); Assert.assertEquals(numMessages, queue.getDeliveringCount()); queue.addConsumer(cons2); Assert.assertEquals(2, queue.getConsumerCount()); queue.acknowledge(ref); queue.addTail(ref); queue.deliverNow(); Assert.assertEquals(0, queue.getScheduledCount()); Assert.assertEquals(numMessages * 2, queue.getDeliveringCount()); queue.acknowledge(ref); queue.addConsumer(cons3);
queue.addConsumer(consumer); queue.pause(); MessageReference ref = generateReference(queue, i); refs.add(ref); queue.addTail(ref); Assert.assertEquals(0, queue.getScheduledCount()); Assert.assertEquals(0, queue.getDeliveringCount()); Assert.assertTrue(consumer.getReferences().isEmpty()); queue.resume(); Assert.assertEquals(numMessages, queue.getDeliveringCount());
doInternalPoll(); deliverAsync(); deliverAsync(); if (paused || !canDispatch() && redistributor == null) { return; noDelivery++; } else { if (checkExpired(ref)) { if (logger.isTraceEnabled()) { logger.trace("Reference " + ref + " being expired"); removeMessageReference(holder, ref); logger.trace("Queue " + this.getName() + " is delivering reference " + ref); final SimpleString groupID = extractGroupID(ref); groupConsumer = getGroupConsumer(groupID); HandleStatus status = handle(ref, consumer); handleMessageGroup(ref, consumer, groupConsumer, groupID); removeMessageReference(holder, ref); handledconsumer = consumer; handled++;
queue.addConsumer(consumer); queue.addTail(ref1); queue.addTail(ref2); queue.addTail(ref3); queue.addTail(ref4); queue.addTail(ref5); queue.addTail(ref6); queue.addConsumer(consumer); queue.deliverNow(); Assert.assertEquals(2, queue.getDeliveringCount()); queue.acknowledge(ref5); queue.acknowledge(ref6); queue.removeConsumer(consumer); queue.addConsumer(consumer); queue.deliverNow();
return false; if (paused || !canDispatch() && redistributor == null) { return false; if (checkExpired(ref)) { return true; Consumer consumer = holder.consumer; final SimpleString groupID = extractGroupID(ref); Consumer groupConsumer = getGroupConsumer(groupID); HandleStatus status = handle(ref, consumer); handleMessageGroup(ref, consumer, groupConsumer, groupID); proceedDeliver(consumer, ref); consumers.reset(); return true; logger.tracef("Queue " + getName() + " is out of direct delivery as no consumers handled a delivery");
final QueueImpl queue = new QueueImpl(1, new SimpleString("address1"), QueueImplTest.queue1, null, null, false, true, false, scheduledExecutor, null, null, null, ArtemisExecutor.delegate(executor), null, null); queue.addConsumer(groupConsumer); queue.addConsumer(noConsumer); final MessageReference firstMessageReference = generateReference(queue, 1); final SimpleString groupName = SimpleString.toSimpleString("group"); final MessageReference secondMessageReference = generateReference(queue, 2); secondMessageReference.getMessage().putStringProperty(Message.HDR_GROUP_ID, groupName); queue.addTail(firstMessageReference, true); Assert.assertTrue("first message isn't handled", firstMessageHandled.await(3000, TimeUnit.MILLISECONDS)); Assert.assertEquals("group consumer isn't correctly set", groupConsumer, queue.getGroups().get(groupName)); queue.addTail(secondMessageReference, true); final boolean atLeastTwoDeliverAttempts = finished.await(3000, TimeUnit.MILLISECONDS); Assert.assertTrue(atLeastTwoDeliverAttempts); Thread.sleep(1000); Assert.assertEquals("The second message should be in the queue", 1, queue.getMessageCount());
@Override public void addTail(final MessageReference ref, final boolean direct) { enterCritical(CRITICAL_PATH_ADD_TAIL); try { if (scheduleIfPossible(ref)) { return; logger.trace("Checking to re-enable direct deliver on queue " + this.getName()); if (deliveriesInTransit.getCount() == 0 && getExecutor().isFlushed() && intermediateMessageReferences.isEmpty() && messageReferences.isEmpty() && !pageIterator.hasNext() && !pageSubscription.isPaging()) { logger.trace("Setting direct deliverer to " + supportsDirectDeliver + " on queue " + this.getName()); logger.trace("Couldn't set direct deliver back on queue " + this.getName()); if (direct && supportsDirectDeliver && directDeliver && deliveriesInTransit.getCount() == 0 && deliverDirect(ref)) { return; deliverAsync(); } finally { leaveCritical(CRITICAL_PATH_ADD_TAIL);
logger.trace("QueueMemorySize before depage on queue=" + this.getName() + " is " + queueMemorySize.get()); while (timeout > System.currentTimeMillis() && needsDepage() && pageIterator.hasNext()) { depaged++; PagedReference reference = pageIterator.next(); if (logger.isTraceEnabled()) { logger.trace("Depaging reference " + reference + " on queue " + this.getName()); addTail(reference, false); pageIterator.remove(); pageSubscription.incrementDeliveredSize(getPersistentSize(reference)); logger.debug("Queue Memory Size after depage on queue=" + this.getName() + " is " + queueMemorySize.get() + " with maxSize = " + maxSize + ". Depaged " + depaged + " messages, pendingDelivery=" + messageReferences.size() + ", intermediateMessageReferences= " + intermediateMessageReferences.size() + ", queueDelivering=" + deliveringMetrics.getMessageCount()); deliverAsync(); expireReferences();
queue.addTail(ref); queue.addHead(ref, false); queue.addTail(ref); queue.addConsumer(consumer); queue.deliverNow();
@Override public void run() { float queueRate = getRate(); if (logger.isDebugEnabled()) { logger.debug(getAddress() + ":" + getName() + " has " + getConsumerCount() + " consumer(s) and is receiving messages at a rate of " + queueRate + " msgs/second."); } else if (queueRate < (threshold * consumers.size())) { if (logger.isDebugEnabled()) { logger.debug("Insufficient messages received on queue \"" + getName() + "\" to satisfy slow-consumer-threshold. Skipping inspection of consumer."); if (queueRate < threshold) { if (logger.isDebugEnabled()) { logger.debug("Insufficient messages received on queue \"" + getName() + "\" to satisfy slow-consumer-threshold. Skipping inspection of consumer."); ActiveMQServerLogger.LOGGER.slowConsumerDetected(serverConsumer.getSessionID(), serverConsumer.getID(), getName().toString(), connection.getRemoteAddress(), threshold, consumerRate); if (policy.equals(SlowConsumerPolicy.KILL)) { connection.killMessage(server.getNodeID()); TypedProperties props = new TypedProperties(); props.putIntProperty(ManagementHelper.HDR_CONSUMER_COUNT, getConsumerCount());
@Override public synchronized boolean changeReferencePriority(final long messageID, final byte newPriority) throws Exception { try (LinkedListIterator<MessageReference> iter = iterator()) { while (iter.hasNext()) { MessageReference ref = iter.next(); if (ref.getMessage().getMessageID() == messageID) { iter.remove(); refRemoved(ref); ref.getMessage().setPriority(newPriority); addTail(ref, false); return true; } } return false; } }
@Override public synchronized boolean deleteReference(final long messageID) throws Exception { boolean deleted = false; Transaction tx = new TransactionImpl(storageManager); try (LinkedListIterator<MessageReference> iter = iterator()) { while (iter.hasNext()) { MessageReference ref = iter.next(); if (ref.getMessage().getMessageID() == messageID) { incDelivering(ref); acknowledge(tx, ref); iter.remove(); refRemoved(ref); deleted = true; break; } } if (!deleted) { // Look in scheduled deliveries deleted = scheduledDeliveryHandler.removeReferenceWithID(messageID) != null ? true : false; } tx.commit(); return deleted; } }
logger.trace("Queue " + this.getName() + " is an internal queue, no checkRedelivery"); if (!internalQueue && reference.isDurable() && isDurableMessage() && !reference.isPaged()) { storageManager.updateDeliveryCount(reference); logger.trace("Sending reference " + reference + " to DLA = " + addressSettings.getDeadLetterAddress() + " since ref.getDeliveryCount=" + reference.getDeliveryCount() + "and maxDeliveries=" + maxDeliveries + " from queue=" + this.getName()); sendToDeadLetterAddress(null, reference, addressSettings.getDeadLetterAddress()); redeliveryDelay = calculateRedeliveryDelay(addressSettings, deliveryCount); if (!reference.isPaged() && reference.isDurable() && isDurableMessage()) { storageManager.updateScheduledDeliveryTime(reference); decDelivering(reference);