Search in sources :

Example 21 with MessageReference

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

the class QueueImplTest method testMessagesAdded.

@Test
public void testMessagesAdded() throws Exception {
    QueueImpl queue = getTemporaryQueue();
    MessageReference messageReference = generateReference(queue, 1);
    MessageReference messageReference2 = generateReference(queue, 2);
    MessageReference messageReference3 = generateReference(queue, 3);
    queue.addTail(messageReference);
    queue.addTail(messageReference2);
    queue.addTail(messageReference3);
    Assert.assertEquals(getMessagesAdded(queue), 3);
}
Also used : MessageReference(org.apache.activemq.artemis.core.server.MessageReference) QueueImpl(org.apache.activemq.artemis.core.server.impl.QueueImpl) Test(org.junit.Test)

Example 22 with MessageReference

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

the class PostOfficeJournalLoader method handleAddMessage.

@Override
public void handleAddMessage(Map<Long, Map<Long, AddMessageRecord>> queueMap) throws Exception {
    for (Map.Entry<Long, Map<Long, AddMessageRecord>> entry : queueMap.entrySet()) {
        long queueID = entry.getKey();
        Map<Long, AddMessageRecord> queueRecords = entry.getValue();
        Queue queue = this.queues.get(queueID);
        if (queue == null) {
            if (queueRecords.values().size() != 0) {
                ActiveMQServerLogger.LOGGER.journalCannotFindQueueForMessage(queueID);
            }
            continue;
        }
        // Redistribution could install a Redistributor while we are still loading records, what will be an issue with
        // prepared ACKs
        // We make sure te Queue is paused before we reroute values.
        queue.pause();
        Collection<AddMessageRecord> valueRecords = queueRecords.values();
        long currentTime = System.currentTimeMillis();
        for (AddMessageRecord record : valueRecords) {
            long scheduledDeliveryTime = record.getScheduledDeliveryTime();
            if (scheduledDeliveryTime != 0 && scheduledDeliveryTime <= currentTime) {
                scheduledDeliveryTime = 0;
                record.getMessage().setScheduledDeliveryTime(0L);
            }
            if (scheduledDeliveryTime != 0) {
                record.getMessage().setScheduledDeliveryTime(scheduledDeliveryTime);
            }
            MessageReference ref = postOffice.reroute(record.getMessage(), queue, null);
            ref.setDeliveryCount(record.getDeliveryCount());
            if (scheduledDeliveryTime != 0) {
                record.getMessage().setScheduledDeliveryTime(0L);
            }
        }
    }
}
Also used : AddMessageRecord(org.apache.activemq.artemis.core.persistence.impl.journal.AddMessageRecord) AtomicLong(java.util.concurrent.atomic.AtomicLong) MessageReference(org.apache.activemq.artemis.core.server.MessageReference) HashMap(java.util.HashMap) Map(java.util.Map) Queue(org.apache.activemq.artemis.core.server.Queue)

Example 23 with MessageReference

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

the class QueueImpl method purgeAfterRollback.

private void purgeAfterRollback(LinkedList<MessageReference> refs) {
    try {
        Transaction transaction = new TransactionImpl(storageManager);
        for (MessageReference reference : refs) {
            // post ack will decrement this, so need to inc
            incDelivering(reference);
            acknowledge(transaction, reference, AckReason.KILLED);
        }
        transaction.commit();
    } catch (Exception e) {
        logger.warn(e.getMessage(), e);
    }
}
Also used : Transaction(org.apache.activemq.artemis.core.transaction.Transaction) TransactionImpl(org.apache.activemq.artemis.core.transaction.impl.TransactionImpl) BindingsTransactionImpl(org.apache.activemq.artemis.core.transaction.impl.BindingsTransactionImpl) MessageReference(org.apache.activemq.artemis.core.server.MessageReference) ActiveMQException(org.apache.activemq.artemis.api.core.ActiveMQException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) NoSuchElementException(java.util.NoSuchElementException)

Example 24 with MessageReference

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

the class QueueImpl method removeReferenceWithID.

@Override
public synchronized MessageReference removeReferenceWithID(final long id1) throws Exception {
    try (LinkedListIterator<MessageReference> iterator = iterator()) {
        MessageReference removed = null;
        while (iterator.hasNext()) {
            MessageReference ref = iterator.next();
            if (ref.getMessage().getMessageID() == id1) {
                iterator.remove();
                refRemoved(ref);
                removed = ref;
                break;
            }
        }
        if (removed == null) {
            // Look in scheduled deliveries
            removed = scheduledDeliveryHandler.removeReferenceWithID(id1);
        }
        return removed;
    }
}
Also used : MessageReference(org.apache.activemq.artemis.core.server.MessageReference)

Example 25 with MessageReference

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

the class QueueImpl method deliver.

/**
 * This method will deliver as many messages as possible until all consumers are busy or there
 * are no more matching or available messages.
 */
private void deliver() {
    if (logger.isDebugEnabled()) {
        logger.debug(this + " doing deliver. messageReferences=" + messageReferences.size());
    }
    doInternalPoll();
    // Either the iterator is empty or the consumer is busy
    int noDelivery = 0;
    int size = 0;
    int endPos = -1;
    int handled = 0;
    long timeout = System.currentTimeMillis() + DELIVERY_TIMEOUT;
    while (true) {
        if (handled == MAX_DELIVERIES_IN_LOOP) {
            // Schedule another one - we do this to prevent a single thread getting caught up in this loop for too
            // long
            deliverAsync();
            return;
        }
        if (System.currentTimeMillis() > timeout) {
            if (logger.isTraceEnabled()) {
                logger.trace("delivery has been running for too long. Scheduling another delivery task now");
            }
            deliverAsync();
            return;
        }
        MessageReference ref;
        Consumer handledconsumer = null;
        synchronized (this) {
            // Need to do these checks inside the synchronized
            if (paused || consumerList.isEmpty()) {
                return;
            }
            if (messageReferences.size() == 0) {
                break;
            }
            if (endPos < 0 || consumersChanged) {
                consumersChanged = false;
                size = consumerList.size();
                endPos = pos - 1;
                if (endPos < 0) {
                    endPos = size - 1;
                    noDelivery = 0;
                }
            }
            ConsumerHolder holder = consumerList.get(pos);
            Consumer consumer = holder.consumer;
            Consumer groupConsumer = null;
            if (holder.iter == null) {
                holder.iter = messageReferences.iterator();
            }
            if (holder.iter.hasNext()) {
                ref = holder.iter.next();
            } else {
                ref = null;
            }
            if (ref == null) {
                noDelivery++;
            } else {
                if (checkExpired(ref)) {
                    if (logger.isTraceEnabled()) {
                        logger.trace("Reference " + ref + " being expired");
                    }
                    holder.iter.remove();
                    refRemoved(ref);
                    handled++;
                    continue;
                }
                if (logger.isTraceEnabled()) {
                    logger.trace("Queue " + this.getName() + " is delivering reference " + ref);
                }
                // If a group id is set, then this overrides the consumer chosen round-robin
                SimpleString groupID = extractGroupID(ref);
                if (groupID != null) {
                    groupConsumer = groups.get(groupID);
                    if (groupConsumer != null) {
                        consumer = groupConsumer;
                    }
                }
                if (exclusive) {
                    consumer = consumerList.get(0).consumer;
                }
                HandleStatus status = handle(ref, consumer);
                if (status == HandleStatus.HANDLED) {
                    deliveriesInTransit.countUp();
                    handledconsumer = consumer;
                    holder.iter.remove();
                    refRemoved(ref);
                    if (groupID != null && groupConsumer == null) {
                        groups.put(groupID, consumer);
                    }
                    handled++;
                } else if (status == HandleStatus.BUSY) {
                    try {
                        holder.iter.repeat();
                    } catch (NoSuchElementException e) {
                        // this could happen if there was an exception on the queue handling
                        // and it returned BUSY because of that exception
                        // 
                        // We will just log it as there's nothing else we can do now.
                        logger.warn(e.getMessage(), e);
                    }
                    noDelivery++;
                } else if (status == HandleStatus.NO_MATCH) {
                // nothing to be done on this case, the iterators will just jump next
                }
            }
            if (pos == endPos) {
                if (noDelivery == size) {
                    if (handledconsumer != null) {
                        // this shouldn't really happen,
                        // however I'm keeping this as an assertion case future developers ever change the logic here on this class
                        ActiveMQServerLogger.LOGGER.nonDeliveryHandled();
                    } else {
                        if (logger.isDebugEnabled()) {
                            logger.debug(this + "::All the consumers were busy, giving up now");
                        }
                        break;
                    }
                }
                noDelivery = 0;
            }
            // When using group we don't need to load balance to the next position
            if (!exclusive && groupConsumer == null) {
                pos++;
            }
            if (pos >= size) {
                pos = 0;
            }
        }
        if (handledconsumer != null) {
            proceedDeliver(handledconsumer, ref);
        }
    }
    checkDepage();
}
Also used : Consumer(org.apache.activemq.artemis.core.server.Consumer) HandleStatus(org.apache.activemq.artemis.core.server.HandleStatus) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) MessageReference(org.apache.activemq.artemis.core.server.MessageReference) NoSuchElementException(java.util.NoSuchElementException)

Aggregations

MessageReference (org.apache.activemq.artemis.core.server.MessageReference)82 ArrayList (java.util.ArrayList)29 QueueImpl (org.apache.activemq.artemis.core.server.impl.QueueImpl)26 Test (org.junit.Test)26 FakeConsumer (org.apache.activemq.artemis.tests.unit.core.server.impl.fakes.FakeConsumer)18 SimpleString (org.apache.activemq.artemis.api.core.SimpleString)17 Transaction (org.apache.activemq.artemis.core.transaction.Transaction)14 Message (org.apache.activemq.artemis.api.core.Message)12 ActiveMQException (org.apache.activemq.artemis.api.core.ActiveMQException)11 TransactionImpl (org.apache.activemq.artemis.core.transaction.impl.TransactionImpl)11 Queue (org.apache.activemq.artemis.core.server.Queue)10 HashMap (java.util.HashMap)9 NoSuchElementException (java.util.NoSuchElementException)9 Map (java.util.Map)8 Filter (org.apache.activemq.artemis.core.filter.Filter)7 LinkedList (java.util.LinkedList)5 ClientMessage (org.apache.activemq.artemis.api.core.client.ClientMessage)5 ActiveMQIllegalStateException (org.apache.activemq.artemis.api.core.ActiveMQIllegalStateException)4 BindingsTransactionImpl (org.apache.activemq.artemis.core.transaction.impl.BindingsTransactionImpl)4 HashSet (java.util.HashSet)3