Search in sources :

Example 21 with SequentialFile

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

the class NIOJournalCompactTest method internalCompactTest.

private void internalCompactTest(final boolean preXA, // prepare before compact
final boolean postXA, // prepare after compact
final boolean regularAdd, final boolean performAppend, final boolean performUpdate, boolean performDelete, boolean performNonTransactionalDelete, final boolean pendingTransactions, final boolean deleteTransactRecords, final boolean delayCommit, final boolean createControlFile, final boolean deleteControlFile, final boolean renameFilesAfterCompacting) throws Exception {
    if (performNonTransactionalDelete) {
        performDelete = false;
    }
    if (performDelete) {
        performNonTransactionalDelete = false;
    }
    setup(2, 60 * 4096, false);
    ArrayList<Long> liveIDs = new ArrayList<>();
    ArrayList<Pair<Long, Long>> transactedRecords = new ArrayList<>();
    final CountDownLatch latchDone = new CountDownLatch(1);
    final CountDownLatch latchWait = new CountDownLatch(1);
    journal = new JournalImpl(fileSize, minFiles, minFiles, 0, 0, fileFactory, filePrefix, fileExtension, maxAIO) {

        @Override
        protected SequentialFile createControlFile(final List<JournalFile> files, final List<JournalFile> newFiles, final Pair<String, String> pair) throws Exception {
            if (createControlFile) {
                return super.createControlFile(files, newFiles, pair);
            } else {
                throw new IllegalStateException("Simulating a crash during compact creation");
            }
        }

        @Override
        protected void deleteControlFile(final SequentialFile controlFile) throws Exception {
            if (deleteControlFile) {
                super.deleteControlFile(controlFile);
            }
        }

        @Override
        protected void renameFiles(final List<JournalFile> oldFiles, final List<JournalFile> newFiles) throws Exception {
            if (renameFilesAfterCompacting) {
                super.renameFiles(oldFiles, newFiles);
            }
        }

        @Override
        public void onCompactDone() {
            latchDone.countDown();
            System.out.println("Waiting on Compact");
            try {
                ActiveMQTestBase.waitForLatch(latchWait);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Done");
        }
    };
    journal.setAutoReclaim(false);
    startJournal();
    load();
    long transactionID = 0;
    if (regularAdd) {
        for (int i = 0; i < NIOJournalCompactTest.NUMBER_OF_RECORDS / 2; i++) {
            add(i);
            if (i % 10 == 0 && i > 0) {
                journal.forceMoveNextFile();
            }
            update(i);
        }
        for (int i = NIOJournalCompactTest.NUMBER_OF_RECORDS / 2; i < NIOJournalCompactTest.NUMBER_OF_RECORDS; i++) {
            addTx(transactionID, i);
            updateTx(transactionID, i);
            if (i % 10 == 0) {
                journal.forceMoveNextFile();
            }
            commit(transactionID++);
            update(i);
        }
    }
    if (pendingTransactions) {
        for (long i = 0; i < 100; i++) {
            long recordID = idGenerator.generateID();
            addTx(transactionID, recordID);
            updateTx(transactionID, recordID);
            if (preXA) {
                prepare(transactionID, new SimpleEncoding(10, (byte) 0));
            }
            transactedRecords.add(new Pair<>(transactionID++, recordID));
        }
    }
    if (regularAdd) {
        for (int i = 0; i < NIOJournalCompactTest.NUMBER_OF_RECORDS; i++) {
            if (!(i % 10 == 0)) {
                delete(i);
            } else {
                liveIDs.add((long) i);
            }
        }
    }
    journal.forceMoveNextFile();
    Thread t = new Thread() {

        @Override
        public void run() {
            try {
                journal.testCompact();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };
    t.start();
    ActiveMQTestBase.waitForLatch(latchDone);
    int nextID = NIOJournalCompactTest.NUMBER_OF_RECORDS;
    if (performAppend) {
        for (int i = 0; i < 50; i++) {
            add(nextID++);
            if (i % 10 == 0) {
                journal.forceMoveNextFile();
            }
        }
        for (int i = 0; i < 50; i++) {
            // A Total new transaction (that was created after the compact started) to add new record while compacting
            // is still working
            addTx(transactionID, nextID++);
            commit(transactionID++);
            if (i % 10 == 0) {
                journal.forceMoveNextFile();
            }
        }
    }
    if (performUpdate) {
        int count = 0;
        for (Long liveID : liveIDs) {
            if (count++ % 2 == 0) {
                update(liveID);
            } else {
                // A Total new transaction (that was created after the compact started) to update a record that is being
                // compacted
                updateTx(transactionID, liveID);
                commit(transactionID++);
            }
        }
    }
    if (performDelete) {
        int count = 0;
        for (long liveID : liveIDs) {
            if (count++ % 2 == 0) {
                System.out.println("Deleting no trans " + liveID);
                delete(liveID);
            } else {
                System.out.println("Deleting TX " + liveID);
                // A Total new transaction (that was created after the compact started) to delete a record that is being
                // compacted
                deleteTx(transactionID, liveID);
                commit(transactionID++);
            }
            System.out.println("Deletes are going into " + ((JournalImpl) journal).getCurrentFile());
        }
    }
    if (performNonTransactionalDelete) {
        for (long liveID : liveIDs) {
            delete(liveID);
        }
    }
    if (pendingTransactions && !delayCommit) {
        for (Pair<Long, Long> tx : transactedRecords) {
            if (postXA) {
                prepare(tx.getA(), new SimpleEncoding(10, (byte) 0));
            }
            if (tx.getA() % 2 == 0) {
                commit(tx.getA());
                if (deleteTransactRecords) {
                    delete(tx.getB());
                }
            } else {
                rollback(tx.getA());
            }
        }
    }
    /**
     * Some independent adds and updates
     */
    for (int i = 0; i < 1000; i++) {
        long id = idGenerator.generateID();
        add(id);
        delete(id);
        if (i % 100 == 0) {
            journal.forceMoveNextFile();
        }
    }
    journal.forceMoveNextFile();
    latchWait.countDown();
    t.join();
    if (pendingTransactions && delayCommit) {
        for (Pair<Long, Long> tx : transactedRecords) {
            if (postXA) {
                prepare(tx.getA(), new SimpleEncoding(10, (byte) 0));
            }
            if (tx.getA() % 2 == 0) {
                commit(tx.getA());
                if (deleteTransactRecords) {
                    delete(tx.getB());
                }
            } else {
                rollback(tx.getA());
            }
        }
    }
    long lastId = idGenerator.generateID();
    add(lastId);
    if (createControlFile && deleteControlFile && renameFilesAfterCompacting) {
        journal.testCompact();
    }
    journal.flush();
    stopJournal();
    createJournal();
    startJournal();
    loadAndCheck();
    journal.forceMoveNextFile();
    update(lastId);
    stopJournal();
    createJournal();
    startJournal();
    loadAndCheck();
}
Also used : SequentialFile(org.apache.activemq.artemis.core.io.SequentialFile) ArrayList(java.util.ArrayList) SimpleEncoding(org.apache.activemq.artemis.tests.unit.core.journal.impl.fakes.SimpleEncoding) CountDownLatch(java.util.concurrent.CountDownLatch) JournalFile(org.apache.activemq.artemis.core.journal.impl.JournalFile) AtomicLong(java.util.concurrent.atomic.AtomicLong) Pair(org.apache.activemq.artemis.api.core.Pair) JournalImpl(org.apache.activemq.artemis.core.journal.impl.JournalImpl)

Example 22 with SequentialFile

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

the class AIOSequentialFileFactoryTest method testBuffer.

@Test
public void testBuffer() throws Exception {
    SequentialFile file = factory.createSequentialFile("filtetmp.log");
    file.open();
    ByteBuffer buff = factory.newBuffer(10);
    Assert.assertEquals(factory.getAlignment(), buff.limit());
    file.close();
    factory.releaseBuffer(buff);
}
Also used : SequentialFile(org.apache.activemq.artemis.core.io.SequentialFile) ByteBuffer(java.nio.ByteBuffer) Test(org.junit.Test)

Example 23 with SequentialFile

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

the class JournalStorageManager method cleanupIncompleteFiles.

private void cleanupIncompleteFiles() throws Exception {
    if (largeMessagesFactory != null) {
        List<String> tmpFiles = largeMessagesFactory.listFiles("tmp");
        for (String tmpFile : tmpFiles) {
            SequentialFile file = largeMessagesFactory.createSequentialFile(tmpFile);
            file.delete();
        }
    }
}
Also used : SequentialFile(org.apache.activemq.artemis.core.io.SequentialFile) SimpleString(org.apache.activemq.artemis.api.core.SimpleString)

Example 24 with SequentialFile

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

the class JournalStorageManager method parseLargeMessage.

@Override
protected /**
 * @param messages
 * @param buff
 * @return
 * @throws Exception
 */
LargeServerMessage parseLargeMessage(final Map<Long, Message> messages, final ActiveMQBuffer buff) throws Exception {
    LargeServerMessage largeMessage = createLargeMessage();
    LargeMessagePersister.getInstance().decode(buff, largeMessage);
    if (largeMessage.containsProperty(Message.HDR_ORIG_MESSAGE_ID)) {
        // for compatibility: couple with old behaviour, copying the old file to avoid message loss
        long originalMessageID = largeMessage.getLongProperty(Message.HDR_ORIG_MESSAGE_ID);
        SequentialFile currentFile = createFileForLargeMessage(largeMessage.getMessageID(), true);
        if (!currentFile.exists()) {
            SequentialFile linkedFile = createFileForLargeMessage(originalMessageID, true);
            if (linkedFile.exists()) {
                linkedFile.copyTo(currentFile);
                linkedFile.close();
            }
        }
        currentFile.close();
    }
    return largeMessage;
}
Also used : SequentialFile(org.apache.activemq.artemis.core.io.SequentialFile) LargeServerMessage(org.apache.activemq.artemis.core.server.LargeServerMessage)

Example 25 with SequentialFile

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

the class JournalStorageManager method recoverPendingLargeMessages.

/**
 * Sets a list of large message files into the replicationManager for synchronization.
 * <p>
 * Collects a list of existing large messages and their current size, passing re.
 * <p>
 * So we know how much of a given message to sync with the backup. Further data appends to the
 * messages will be replicated normally.
 *
 * @throws Exception
 */
private Map<Long, Pair<String, Long>> recoverPendingLargeMessages() throws Exception {
    Map<Long, Pair<String, Long>> largeMessages = new HashMap<>();
    // only send durable messages... // listFiles append a "." to anything...
    List<String> filenames = largeMessagesFactory.listFiles("msg");
    List<Long> idList = new ArrayList<>();
    for (String filename : filenames) {
        Long id = getLargeMessageIdFromFilename(filename);
        if (!largeMessagesToDelete.contains(id)) {
            idList.add(id);
            SequentialFile seqFile = largeMessagesFactory.createSequentialFile(filename);
            long size = seqFile.size();
            largeMessages.put(id, new Pair<>(filename, size));
        }
    }
    return largeMessages;
}
Also used : SequentialFile(org.apache.activemq.artemis.core.io.SequentialFile) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) SimpleString(org.apache.activemq.artemis.api.core.SimpleString) Pair(org.apache.activemq.artemis.api.core.Pair)

Aggregations

SequentialFile (org.apache.activemq.artemis.core.io.SequentialFile)53 Test (org.junit.Test)21 ByteBuffer (java.nio.ByteBuffer)15 ArrayList (java.util.ArrayList)10 SimpleString (org.apache.activemq.artemis.api.core.SimpleString)9 ActiveMQBuffer (org.apache.activemq.artemis.api.core.ActiveMQBuffer)7 Pair (org.apache.activemq.artemis.api.core.Pair)5 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)4 SequentialFileFactory (org.apache.activemq.artemis.core.io.SequentialFileFactory)4 NIOSequentialFileFactory (org.apache.activemq.artemis.core.io.nio.NIOSequentialFileFactory)4 Page (org.apache.activemq.artemis.core.paging.impl.Page)4 JDBCSequentialFile (org.apache.activemq.artemis.jdbc.store.file.JDBCSequentialFile)4 SimpleEncoding (org.apache.activemq.artemis.tests.unit.core.journal.impl.fakes.SimpleEncoding)4 ActiveMQException (org.apache.activemq.artemis.api.core.ActiveMQException)3 IOCriticalErrorListener (org.apache.activemq.artemis.core.io.IOCriticalErrorListener)3 PagedMessage (org.apache.activemq.artemis.core.paging.PagedMessage)3 File (java.io.File)2 IOException (java.io.IOException)2 HashMap (java.util.HashMap)2 CountDownLatch (java.util.concurrent.CountDownLatch)2