Search in sources :

Example 26 with IOCallback

use of org.apache.activemq.artemis.core.io.IOCallback in project activemq-artemis by apache.

the class NIOJournalCompactTest method testStressDeletesNoSync.

@Test
public void testStressDeletesNoSync() throws Throwable {
    Configuration config = createBasicConfig().setJournalFileSize(100 * 1024).setJournalSyncNonTransactional(false).setJournalSyncTransactional(false).setJournalCompactMinFiles(0).setJournalCompactPercentage(0);
    final AtomicInteger errors = new AtomicInteger(0);
    final AtomicBoolean running = new AtomicBoolean(true);
    final AtomicLong seqGenerator = new AtomicLong(1);
    final ExecutorService executor = Executors.newCachedThreadPool(ActiveMQThreadFactory.defaultThreadFactory());
    final ExecutorService ioexecutor = Executors.newCachedThreadPool(ActiveMQThreadFactory.defaultThreadFactory());
    OrderedExecutorFactory factory = new OrderedExecutorFactory(executor);
    OrderedExecutorFactory iofactory = new OrderedExecutorFactory(ioexecutor);
    final ExecutorService deleteExecutor = Executors.newCachedThreadPool(ActiveMQThreadFactory.defaultThreadFactory());
    final JournalStorageManager storage = new JournalStorageManager(config, EmptyCriticalAnalyzer.getInstance(), factory, iofactory);
    storage.start();
    try {
        storage.loadInternalOnly();
        ((JournalImpl) storage.getMessageJournal()).setAutoReclaim(false);
        final LinkedList<Long> survivingMsgs = new LinkedList<>();
        Runnable producerRunnable = new Runnable() {

            @Override
            public void run() {
                try {
                    while (running.get()) {
                        final long[] values = new long[100];
                        long tx = seqGenerator.incrementAndGet();
                        OperationContextImpl ctx = new OperationContextImpl(executor);
                        storage.setContext(ctx);
                        for (int i = 0; i < 100; i++) {
                            long id = seqGenerator.incrementAndGet();
                            values[i] = id;
                            CoreMessage message = new CoreMessage(id, 100);
                            message.getBodyBuffer().writeBytes(new byte[1024]);
                            storage.storeMessageTransactional(tx, message);
                        }
                        CoreMessage message = new CoreMessage(seqGenerator.incrementAndGet(), 100);
                        survivingMsgs.add(message.getMessageID());
                        logger.info("Going to store " + message);
                        // This one will stay here forever
                        storage.storeMessage(message);
                        logger.info("message storeed " + message);
                        logger.info("Going to commit " + tx);
                        storage.commit(tx);
                        logger.info("Committed " + tx);
                        ctx.executeOnCompletion(new IOCallback() {

                            @Override
                            public void onError(int errorCode, String errorMessage) {
                            }

                            @Override
                            public void done() {
                                deleteExecutor.execute(new Runnable() {

                                    @Override
                                    public void run() {
                                        try {
                                            for (long messageID : values) {
                                                storage.deleteMessage(messageID);
                                            }
                                        } catch (Throwable e) {
                                            e.printStackTrace();
                                            errors.incrementAndGet();
                                        }
                                    }
                                });
                            }
                        });
                    }
                } catch (Throwable e) {
                    e.printStackTrace();
                    errors.incrementAndGet();
                }
            }
        };
        Runnable compressRunnable = new Runnable() {

            @Override
            public void run() {
                try {
                    while (running.get()) {
                        Thread.sleep(500);
                        System.out.println("Compacting");
                        ((JournalImpl) storage.getMessageJournal()).testCompact();
                        ((JournalImpl) storage.getMessageJournal()).checkReclaimStatus();
                    }
                } catch (Throwable e) {
                    e.printStackTrace();
                    errors.incrementAndGet();
                }
            }
        };
        Thread producerThread = new Thread(producerRunnable);
        producerThread.start();
        Thread compactorThread = new Thread(compressRunnable);
        compactorThread.start();
        Thread.sleep(1000);
        running.set(false);
        producerThread.join();
        compactorThread.join();
        deleteExecutor.shutdown();
        assertTrue("delete executor failted to terminate", deleteExecutor.awaitTermination(30, TimeUnit.SECONDS));
        storage.stop();
        executor.shutdown();
        assertTrue("executor failed to terminate", executor.awaitTermination(30, TimeUnit.SECONDS));
        ioexecutor.shutdown();
        assertTrue("ioexecutor failed to terminate", ioexecutor.awaitTermination(30, TimeUnit.SECONDS));
        Assert.assertEquals(0, errors.get());
    } catch (Throwable e) {
        e.printStackTrace();
        throw e;
    } finally {
        try {
            storage.stop();
        } catch (Exception e) {
            e.printStackTrace();
        }
        executor.shutdownNow();
        deleteExecutor.shutdownNow();
        ioexecutor.shutdownNow();
    }
}
Also used : OrderedExecutorFactory(org.apache.activemq.artemis.utils.actors.OrderedExecutorFactory) Configuration(org.apache.activemq.artemis.core.config.Configuration) OperationContextImpl(org.apache.activemq.artemis.core.persistence.impl.journal.OperationContextImpl) IOCallback(org.apache.activemq.artemis.core.io.IOCallback) LinkedList(java.util.LinkedList) CoreMessage(org.apache.activemq.artemis.core.message.impl.CoreMessage) JournalStorageManager(org.apache.activemq.artemis.core.persistence.impl.journal.JournalStorageManager) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicLong(java.util.concurrent.atomic.AtomicLong) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ExecutorService(java.util.concurrent.ExecutorService) AtomicLong(java.util.concurrent.atomic.AtomicLong) JournalImpl(org.apache.activemq.artemis.core.journal.impl.JournalImpl) Test(org.junit.Test)

Example 27 with IOCallback

use of org.apache.activemq.artemis.core.io.IOCallback in project activemq-artemis by apache.

the class ProtonServerSenderContext method onMessage.

@Override
public void onMessage(Delivery delivery) throws ActiveMQAMQPException {
    if (closed) {
        return;
    }
    OperationContext oldContext = sessionSPI.recoverContext();
    try {
        Message message = ((MessageReference) delivery.getContext()).getMessage();
        boolean preSettle = sender.getRemoteSenderSettleMode() == SenderSettleMode.SETTLED;
        DeliveryState remoteState;
        connection.lock();
        try {
            remoteState = delivery.getRemoteState();
        } finally {
            connection.unlock();
        }
        boolean settleImmediate = true;
        if (remoteState instanceof Accepted) {
            // acking again would show an exception but would have no negative effect but best to handle anyway.
            if (delivery.isSettled()) {
                return;
            }
            // from dealer, a perf hit but a must
            try {
                sessionSPI.ack(null, brokerConsumer, message);
            } catch (Exception e) {
                log.warn(e.toString(), e);
                throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorAcknowledgingMessage(message.toString(), e.getMessage());
            }
        } else if (remoteState instanceof TransactionalState) {
            // When the message arrives with a TransactionState disposition the ack should
            // enlist the message into the transaction associated with the given txn ID.
            TransactionalState txState = (TransactionalState) remoteState;
            ProtonTransactionImpl tx = (ProtonTransactionImpl) this.sessionSPI.getTransaction(txState.getTxnId(), false);
            if (txState.getOutcome() != null) {
                settleImmediate = false;
                Outcome outcome = txState.getOutcome();
                if (outcome instanceof Accepted) {
                    if (!delivery.remotelySettled()) {
                        TransactionalState txAccepted = new TransactionalState();
                        txAccepted.setOutcome(Accepted.getInstance());
                        txAccepted.setTxnId(txState.getTxnId());
                        connection.lock();
                        try {
                            delivery.disposition(txAccepted);
                        } finally {
                            connection.unlock();
                        }
                    }
                    // from dealer, a perf hit but a must
                    try {
                        sessionSPI.ack(tx, brokerConsumer, message);
                        tx.addDelivery(delivery, this);
                    } catch (Exception e) {
                        throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorAcknowledgingMessage(message.toString(), e.getMessage());
                    }
                }
            }
        } else if (remoteState instanceof Released) {
            try {
                sessionSPI.cancel(brokerConsumer, message, false);
            } catch (Exception e) {
                throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorCancellingMessage(message.toString(), e.getMessage());
            }
        } else if (remoteState instanceof Rejected) {
            try {
                sessionSPI.reject(brokerConsumer, message);
            } catch (Exception e) {
                throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorCancellingMessage(message.toString(), e.getMessage());
            }
        } else if (remoteState instanceof Modified) {
            try {
                Modified modification = (Modified) remoteState;
                if (Boolean.TRUE.equals(modification.getUndeliverableHere())) {
                    message.rejectConsumer(brokerConsumer.sequentialID());
                }
                if (Boolean.TRUE.equals(modification.getDeliveryFailed())) {
                    sessionSPI.cancel(brokerConsumer, message, true);
                } else {
                    sessionSPI.cancel(brokerConsumer, message, false);
                }
            } catch (Exception e) {
                throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.errorCancellingMessage(message.toString(), e.getMessage());
            }
        } else {
            log.debug("Received null or unknown disposition for delivery update: " + remoteState);
            return;
        }
        if (!preSettle) {
            protonSession.replaceTag(delivery.getTag());
        }
        if (settleImmediate) {
            settle(delivery);
        }
    } finally {
        sessionSPI.afterIO(new IOCallback() {

            @Override
            public void done() {
                connection.flush();
            }

            @Override
            public void onError(int errorCode, String errorMessage) {
                connection.flush();
            }
        });
        sessionSPI.resetContext(oldContext);
    }
}
Also used : OperationContext(org.apache.activemq.artemis.core.persistence.OperationContext) Released(org.apache.qpid.proton.amqp.messaging.Released) Modified(org.apache.qpid.proton.amqp.messaging.Modified) AMQPMessage(org.apache.activemq.artemis.protocol.amqp.broker.AMQPMessage) Message(org.apache.activemq.artemis.api.core.Message) Rejected(org.apache.qpid.proton.amqp.messaging.Rejected) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) MessageReference(org.apache.activemq.artemis.core.server.MessageReference) IOCallback(org.apache.activemq.artemis.core.io.IOCallback) Accepted(org.apache.qpid.proton.amqp.messaging.Accepted) ActiveMQAMQPNotFoundException(org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPNotFoundException) ActiveMQAMQPException(org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPException) FilterException(org.apache.activemq.artemis.selector.filter.FilterException) ActiveMQAMQPInternalErrorException(org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPInternalErrorException) ActiveMQQueueExistsException(org.apache.activemq.artemis.api.core.ActiveMQQueueExistsException) ActiveMQAMQPResourceLimitExceededException(org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPResourceLimitExceededException) ActiveMQAMQPIllegalStateException(org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPIllegalStateException) ActiveMQSecurityException(org.apache.activemq.artemis.api.core.ActiveMQSecurityException) TransactionalState(org.apache.qpid.proton.amqp.transaction.TransactionalState) DeliveryState(org.apache.qpid.proton.amqp.transport.DeliveryState) Outcome(org.apache.qpid.proton.amqp.messaging.Outcome) ProtonTransactionImpl(org.apache.activemq.artemis.protocol.amqp.proton.transaction.ProtonTransactionImpl)

Aggregations

IOCallback (org.apache.activemq.artemis.core.io.IOCallback)27 SimpleString (org.apache.activemq.artemis.api.core.SimpleString)12 Test (org.junit.Test)9 CountDownLatch (java.util.concurrent.CountDownLatch)7 ArrayList (java.util.ArrayList)6 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)6 ByteBuffer (java.nio.ByteBuffer)4 ExecutorService (java.util.concurrent.ExecutorService)3 ActiveMQIllegalStateException (org.apache.activemq.artemis.api.core.ActiveMQIllegalStateException)3 OperationContext (org.apache.activemq.artemis.core.persistence.OperationContext)3 JournalStorageManager (org.apache.activemq.artemis.core.persistence.impl.journal.JournalStorageManager)3 OperationContextImpl (org.apache.activemq.artemis.core.persistence.impl.journal.OperationContextImpl)3 IOException (java.io.IOException)2 ActiveMQQueueExistsException (org.apache.activemq.artemis.api.core.ActiveMQQueueExistsException)2 Message (org.apache.activemq.artemis.api.core.Message)2 Journal (org.apache.activemq.artemis.core.journal.Journal)2 SimpleWaitIOCallback (org.apache.activemq.artemis.core.journal.impl.SimpleWaitIOCallback)2 StorageManager (org.apache.activemq.artemis.core.persistence.StorageManager)2 ReplicatedJournal (org.apache.activemq.artemis.core.replication.ReplicatedJournal)2 MessageReference (org.apache.activemq.artemis.core.server.MessageReference)2