Search in sources :

Example 26 with TransactionImpl

use of org.apache.activemq.artemis.core.transaction.impl.TransactionImpl in project activemq-artemis by apache.

the class ScaleDownHandler method scaleDownRegularMessages.

public long scaleDownRegularMessages(final SimpleString address, final Set<Queue> queues, final ClientSession clientSession, final ClientProducer producer) throws Exception {
    logger.debug("Scaling down messages on address " + address);
    long messageCount = 0;
    final HashMap<Queue, QueuesXRefInnerManager> controls = new HashMap<>();
    PagingStore pageStore = pagingManager.getPageStore(address);
    Transaction tx = new TransactionImpl(storageManager);
    pageStore.disableCleanup();
    try {
        for (Queue queue : queues) {
            controls.put(queue, new QueuesXRefInnerManager(clientSession, queue, pageStore));
        }
        // compile a list of all the relevant queues and queue iterators for this address
        for (Queue loopQueue : queues) {
            logger.debug("Scaling down messages on address " + address + " / performing loop on queue " + loopQueue);
            try (LinkedListIterator<MessageReference> messagesIterator = loopQueue.browserIterator()) {
                while (messagesIterator.hasNext()) {
                    MessageReference messageReference = messagesIterator.next();
                    Message message = messageReference.getMessage().copy();
                    logger.debug("Reading message " + message + " from queue " + loopQueue);
                    Set<QueuesXRefInnerManager> queuesFound = new HashSet<>();
                    for (Map.Entry<Queue, QueuesXRefInnerManager> controlEntry : controls.entrySet()) {
                        if (controlEntry.getKey() == loopQueue) {
                            // no need to lookup on itself, we just add it
                            queuesFound.add(controlEntry.getValue());
                        } else if (controlEntry.getValue().lookup(messageReference)) {
                            logger.debug("Message existed on queue " + controlEntry.getKey().getID() + " removeID=" + controlEntry.getValue().getQueueID());
                            queuesFound.add(controlEntry.getValue());
                        }
                    }
                    // get the ID for every queue that contains the message
                    ByteBuffer buffer = ByteBuffer.allocate(queuesFound.size() * 8);
                    for (QueuesXRefInnerManager control : queuesFound) {
                        long queueID = control.getQueueID();
                        buffer.putLong(queueID);
                    }
                    message.putBytesProperty(Message.HDR_ROUTE_TO_IDS.toString(), buffer.array());
                    if (logger.isDebugEnabled()) {
                        if (messageReference.isPaged()) {
                            logger.debug("*********************<<<<< Scaling down pdgmessage " + message);
                        } else {
                            logger.debug("*********************<<<<< Scaling down message " + message);
                        }
                    }
                    producer.send(address, message);
                    messageCount++;
                    messagesIterator.remove();
                    // We need to perform the ack / removal after sending, otherwise the message could been removed before the send is finished
                    for (QueuesXRefInnerManager queueFound : queuesFound) {
                        ackMessageOnQueue(tx, queueFound.getQueue(), messageReference);
                    }
                }
            } catch (NoSuchElementException ignored) {
            // this could happen through paging browsing
            }
        }
        tx.commit();
        for (QueuesXRefInnerManager controlRemoved : controls.values()) {
            controlRemoved.close();
        }
        return messageCount;
    } finally {
        pageStore.enableCleanup();
        pageStore.getCursorProvider().scheduleCleanup();
    }
}
Also used : ClientMessage(org.apache.activemq.artemis.api.core.client.ClientMessage) Message(org.apache.activemq.artemis.api.core.Message) HashMap(java.util.HashMap) TransactionImpl(org.apache.activemq.artemis.core.transaction.impl.TransactionImpl) MessageReference(org.apache.activemq.artemis.core.server.MessageReference) ByteBuffer(java.nio.ByteBuffer) Transaction(org.apache.activemq.artemis.core.transaction.Transaction) Queue(org.apache.activemq.artemis.core.server.Queue) PagingStore(org.apache.activemq.artemis.core.paging.PagingStore) HashMap(java.util.HashMap) Map(java.util.Map) NoSuchElementException(java.util.NoSuchElementException) HashSet(java.util.HashSet)

Example 27 with TransactionImpl

use of org.apache.activemq.artemis.core.transaction.impl.TransactionImpl in project activemq-artemis by apache.

the class ServerConsumerImpl method individualAcknowledge.

@Override
public synchronized void individualAcknowledge(Transaction tx, final long messageID) throws Exception {
    if (browseOnly) {
        return;
    }
    boolean startedTransaction = false;
    if (logger.isTraceEnabled()) {
        logger.trace("individualACK messageID=" + messageID);
    }
    if (tx == null) {
        if (logger.isTraceEnabled()) {
            logger.trace("individualACK starting new TX");
        }
        startedTransaction = true;
        tx = new TransactionImpl(storageManager);
    }
    try {
        MessageReference ref;
        ref = removeReferenceByID(messageID);
        if (logger.isTraceEnabled()) {
            logger.trace("ACKing ref " + ref + " on tx= " + tx + ", consumer=" + this);
        }
        if (ref == null) {
            ActiveMQIllegalStateException ils = new ActiveMQIllegalStateException("Cannot find ref to ack " + messageID);
            tx.markAsRollbackOnly(ils);
            throw ils;
        }
        ref.acknowledge(tx);
        acks++;
        if (startedTransaction) {
            tx.commit();
        }
    } catch (ActiveMQException e) {
        if (startedTransaction) {
            tx.rollback();
        } else {
            tx.markAsRollbackOnly(e);
        }
        throw e;
    } catch (Throwable e) {
        ActiveMQServerLogger.LOGGER.errorAckingMessage((Exception) e);
        ActiveMQIllegalStateException hqex = new ActiveMQIllegalStateException(e.getMessage());
        if (startedTransaction) {
            tx.rollback();
        } else {
            tx.markAsRollbackOnly(hqex);
        }
        throw hqex;
    }
}
Also used : ActiveMQException(org.apache.activemq.artemis.api.core.ActiveMQException) ActiveMQIllegalStateException(org.apache.activemq.artemis.api.core.ActiveMQIllegalStateException) TransactionImpl(org.apache.activemq.artemis.core.transaction.impl.TransactionImpl) MessageReference(org.apache.activemq.artemis.core.server.MessageReference) ActiveMQException(org.apache.activemq.artemis.api.core.ActiveMQException) ActiveMQIllegalStateException(org.apache.activemq.artemis.api.core.ActiveMQIllegalStateException)

Example 28 with TransactionImpl

use of org.apache.activemq.artemis.core.transaction.impl.TransactionImpl in project activemq-artemis by apache.

the class RefsOperation method afterRollback.

@Override
public void afterRollback(final Transaction tx) {
    Map<QueueImpl, LinkedList<MessageReference>> queueMap = new HashMap<>();
    long timeBase = System.currentTimeMillis();
    // add any already acked refs, this means that they have been transferred via a producer.send() and have no
    // previous state persisted.
    List<MessageReference> ackedRefs = new ArrayList<>();
    for (MessageReference ref : refsToAck) {
        ref.emptyConsumerID();
        if (logger.isTraceEnabled()) {
            logger.trace("rolling back " + ref);
        }
        try {
            if (ref.isAlreadyAcked()) {
                ackedRefs.add(ref);
            }
            rollbackRedelivery(tx, ref, timeBase, queueMap);
        } catch (Exception e) {
            ActiveMQServerLogger.LOGGER.errorCheckingDLQ(e);
        }
    }
    for (Map.Entry<QueueImpl, LinkedList<MessageReference>> entry : queueMap.entrySet()) {
        LinkedList<MessageReference> refs = entry.getValue();
        QueueImpl queue = entry.getKey();
        synchronized (queue) {
            queue.postRollback(refs);
        }
    }
    if (!ackedRefs.isEmpty()) {
        // message references
        try {
            Transaction ackedTX = new TransactionImpl(storageManager);
            for (MessageReference ref : ackedRefs) {
                Message message = ref.getMessage();
                if (message.isDurable()) {
                    int durableRefCount = message.incrementDurableRefCount();
                    if (durableRefCount == 1) {
                        storageManager.storeMessageTransactional(ackedTX.getID(), message);
                    }
                    Queue queue = ref.getQueue();
                    storageManager.storeReferenceTransactional(ackedTX.getID(), queue.getID(), message.getMessageID());
                    ackedTX.setContainsPersistent();
                }
                message.incrementRefCount();
            }
            ackedTX.commit(true);
        } catch (Exception e) {
            ActiveMQServerLogger.LOGGER.failedToProcessMessageReferenceAfterRollback(e);
        }
    }
}
Also used : Message(org.apache.activemq.artemis.api.core.Message) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) TransactionImpl(org.apache.activemq.artemis.core.transaction.impl.TransactionImpl) MessageReference(org.apache.activemq.artemis.core.server.MessageReference) LinkedList(java.util.LinkedList) Transaction(org.apache.activemq.artemis.core.transaction.Transaction) HashMap(java.util.HashMap) Map(java.util.Map) Queue(org.apache.activemq.artemis.core.server.Queue)

Example 29 with TransactionImpl

use of org.apache.activemq.artemis.core.transaction.impl.TransactionImpl in project activemq-artemis by apache.

the class PagingCounterTest method testCleanupCounter.

@Test
public void testCleanupCounter() throws Exception {
    ClientSessionFactory sf = createSessionFactory(sl);
    ClientSession session = sf.createSession();
    try {
        server.addAddressInfo(new AddressInfo(new SimpleString("A1"), RoutingType.ANYCAST));
        Queue queue = server.createQueue(new SimpleString("A1"), RoutingType.ANYCAST, new SimpleString("A1"), null, true, false);
        PageSubscriptionCounter counter = locateCounter(queue);
        StorageManager storage = server.getStorageManager();
        Transaction tx = new TransactionImpl(server.getStorageManager());
        for (int i = 0; i < 2100; i++) {
            counter.increment(tx, 1, 1000);
            if (i % 200 == 0) {
                tx.commit();
                storage.waitOnOperations();
                assertEquals(i + 1, counter.getValue());
                assertEquals((i + 1) * 1000, counter.getPersistentSize());
                tx = new TransactionImpl(server.getStorageManager());
            }
        }
        tx.commit();
        storage.waitOnOperations();
        assertEquals(2100, counter.getValue());
        assertEquals(2100 * 1000, counter.getPersistentSize());
        server.stop();
        server = newActiveMQServer();
        server.start();
        queue = server.locateQueue(new SimpleString("A1"));
        assertNotNull(queue);
        counter = locateCounter(queue);
        assertEquals(2100, counter.getValue());
        assertEquals(2100 * 1000, counter.getPersistentSize());
    } finally {
        sf.close();
        session.close();
    }
}
Also used : Transaction(org.apache.activemq.artemis.core.transaction.Transaction) ClientSession(org.apache.activemq.artemis.api.core.client.ClientSession) StorageManager(org.apache.activemq.artemis.core.persistence.StorageManager) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) PageSubscriptionCounter(org.apache.activemq.artemis.core.paging.cursor.PageSubscriptionCounter) ClientSessionFactory(org.apache.activemq.artemis.api.core.client.ClientSessionFactory) TransactionImpl(org.apache.activemq.artemis.core.transaction.impl.TransactionImpl) Queue(org.apache.activemq.artemis.core.server.Queue) AddressInfo(org.apache.activemq.artemis.core.server.impl.AddressInfo) Test(org.junit.Test)

Example 30 with TransactionImpl

use of org.apache.activemq.artemis.core.transaction.impl.TransactionImpl in project activemq-artemis by apache.

the class PagingCounterTest method testRestartCounter.

@Test
public void testRestartCounter() throws Exception {
    server.addAddressInfo(new AddressInfo(new SimpleString("A1"), RoutingType.ANYCAST));
    Queue queue = server.createQueue(new SimpleString("A1"), RoutingType.ANYCAST, new SimpleString("A1"), null, true, false);
    PageSubscriptionCounter counter = locateCounter(queue);
    StorageManager storage = server.getStorageManager();
    Transaction tx = new TransactionImpl(server.getStorageManager());
    counter.increment(tx, 1, 1000);
    assertEquals(0, counter.getValue());
    assertEquals(0, counter.getPersistentSize());
    tx.commit();
    storage.waitOnOperations();
    assertEquals(1, counter.getValue());
    assertEquals(1000, counter.getPersistentSize());
    sl.close();
    server.stop();
    server = newActiveMQServer();
    server.start();
    queue = server.locateQueue(new SimpleString("A1"));
    assertNotNull(queue);
    counter = locateCounter(queue);
    assertEquals(1, counter.getValue());
    assertEquals(1000, counter.getPersistentSize());
}
Also used : Transaction(org.apache.activemq.artemis.core.transaction.Transaction) StorageManager(org.apache.activemq.artemis.core.persistence.StorageManager) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) PageSubscriptionCounter(org.apache.activemq.artemis.core.paging.cursor.PageSubscriptionCounter) TransactionImpl(org.apache.activemq.artemis.core.transaction.impl.TransactionImpl) Queue(org.apache.activemq.artemis.core.server.Queue) AddressInfo(org.apache.activemq.artemis.core.server.impl.AddressInfo) Test(org.junit.Test)

Aggregations

TransactionImpl (org.apache.activemq.artemis.core.transaction.impl.TransactionImpl)31 Transaction (org.apache.activemq.artemis.core.transaction.Transaction)24 SimpleString (org.apache.activemq.artemis.api.core.SimpleString)11 MessageReference (org.apache.activemq.artemis.core.server.MessageReference)11 Test (org.junit.Test)10 Queue (org.apache.activemq.artemis.core.server.Queue)9 Message (org.apache.activemq.artemis.api.core.Message)8 PageSubscriptionCounter (org.apache.activemq.artemis.core.paging.cursor.PageSubscriptionCounter)7 StorageManager (org.apache.activemq.artemis.core.persistence.StorageManager)7 ArrayList (java.util.ArrayList)6 HashMap (java.util.HashMap)6 ActiveMQException (org.apache.activemq.artemis.api.core.ActiveMQException)5 PageSubscription (org.apache.activemq.artemis.core.paging.cursor.PageSubscription)5 DuplicateIDCache (org.apache.activemq.artemis.core.postoffice.DuplicateIDCache)5 BindingsTransactionImpl (org.apache.activemq.artemis.core.transaction.impl.BindingsTransactionImpl)5 Map (java.util.Map)4 ClientSession (org.apache.activemq.artemis.api.core.client.ClientSession)4 ClientSessionFactory (org.apache.activemq.artemis.api.core.client.ClientSessionFactory)4 LinkedList (java.util.LinkedList)3 NoSuchElementException (java.util.NoSuchElementException)3