use of org.apache.activemq.artemis.core.journal.Journal in project activemq-artemis by apache.
the class JournalStorageManager method init.
@Override
protected void init(Configuration config, IOCriticalErrorListener criticalErrorListener) {
if (!EnumSet.allOf(JournalType.class).contains(config.getJournalType())) {
throw ActiveMQMessageBundle.BUNDLE.invalidJournal();
}
bindingsFF = new NIOSequentialFileFactory(config.getBindingsLocation(), criticalErrorListener, config.getJournalMaxIO_NIO());
bindingsFF.setDatasync(config.isJournalDatasync());
Journal localBindings = new JournalImpl(ioExecutorFactory, 1024 * 1024, 2, config.getJournalCompactMinFiles(), config.getJournalPoolFiles(), config.getJournalCompactPercentage(), config.getJournalFileOpenTimeout(), bindingsFF, "activemq-bindings", "bindings", 1, 0, criticalErrorListener);
bindingsJournal = localBindings;
originalBindingsJournal = localBindings;
switch(config.getJournalType()) {
case NIO:
if (criticalErrorListener != null) {
ActiveMQServerLogger.LOGGER.journalUseNIO();
}
journalFF = new NIOSequentialFileFactory(config.getJournalLocation(), true, config.getJournalBufferSize_NIO(), config.getJournalBufferTimeout_NIO(), config.getJournalMaxIO_NIO(), config.isLogJournalWriteRate(), criticalErrorListener, getCriticalAnalyzer());
break;
case ASYNCIO:
if (criticalErrorListener != null) {
ActiveMQServerLogger.LOGGER.journalUseAIO();
}
journalFF = new AIOSequentialFileFactory(config.getJournalLocation(), config.getJournalBufferSize_AIO(), config.getJournalBufferTimeout_AIO(), config.getJournalMaxIO_AIO(), config.isLogJournalWriteRate(), criticalErrorListener, getCriticalAnalyzer());
break;
case MAPPED:
if (criticalErrorListener != null) {
ActiveMQServerLogger.LOGGER.journalUseMAPPED();
}
journalFF = new MappedSequentialFileFactory(config.getJournalLocation(), config.getJournalFileSize(), true, config.getJournalBufferSize_NIO(), config.getJournalBufferTimeout_NIO(), criticalErrorListener);
break;
default:
throw ActiveMQMessageBundle.BUNDLE.invalidJournalType2(config.getJournalType());
}
journalFF.setDatasync(config.isJournalDatasync());
int fileSize = config.getJournalFileSize();
// we need to correct the file size if its not a multiple of the alignement
int modulus = fileSize % journalFF.getAlignment();
if (modulus != 0) {
int difference = modulus;
int low = config.getJournalFileSize() - difference;
int high = low + journalFF.getAlignment();
fileSize = difference < journalFF.getAlignment() / 2 ? low : high;
ActiveMQServerLogger.LOGGER.invalidJournalFileSize(config.getJournalFileSize(), fileSize, journalFF.getAlignment());
}
Journal localMessage = createMessageJournal(config, criticalErrorListener, fileSize);
messageJournal = localMessage;
originalMessageJournal = localMessage;
largeMessagesDirectory = config.getLargeMessagesDirectory();
largeMessagesFactory = new NIOSequentialFileFactory(config.getLargeMessagesLocation(), false, criticalErrorListener, 1);
if (config.getPageMaxConcurrentIO() != 1) {
pageMaxConcurrentIO = new Semaphore(config.getPageMaxConcurrentIO());
} else {
pageMaxConcurrentIO = null;
}
}
use of org.apache.activemq.artemis.core.journal.Journal in project activemq-artemis by apache.
the class ReplicationEndpoint method stop.
@Override
public synchronized void stop() throws Exception {
if (!started) {
return;
}
logger.trace("Stopping endpoint");
started = false;
OrderedExecutorFactory.flushExecutor(executor);
// Channel may be null if there isn't a connection to a live server
if (channel != null) {
channel.close();
}
for (ReplicatedLargeMessage largeMessage : largeMessages.values()) {
largeMessage.releaseResources();
}
largeMessages.clear();
for (Entry<JournalContent, Map<Long, JournalSyncFile>> entry : filesReservedForSync.entrySet()) {
for (JournalSyncFile filesReserved : entry.getValue().values()) {
filesReserved.close();
}
}
filesReservedForSync.clear();
if (journals != null) {
for (Journal j : journals) {
if (j instanceof FileWrapperJournal)
j.stop();
}
}
for (ConcurrentMap<Integer, Page> map : pageIndex.values()) {
for (Page page : map.values()) {
try {
page.sync();
page.close(false);
} catch (Exception e) {
ActiveMQServerLogger.LOGGER.errorClosingPageOnReplication(e);
}
}
}
pageManager.stop();
pageIndex.clear();
// Storage needs to be the last to stop
storageManager.stop();
started = false;
}
use of org.apache.activemq.artemis.core.journal.Journal in project activemq-artemis by apache.
the class ReplicationEndpoint method handleStartReplicationSynchronization.
/**
* Reserves files (with the given fileID) in the specified journal, and places a
* {@link FileWrapperJournal} in place to store messages while synchronization is going on.
*
* @param packet
* @return if the incoming packet indicates the synchronization is finished then return an acknowledgement otherwise
* return an empty response
* @throws Exception
*/
private ReplicationResponseMessageV2 handleStartReplicationSynchronization(final ReplicationStartSyncMessage packet) throws Exception {
if (logger.isTraceEnabled()) {
logger.trace("handleStartReplicationSynchronization:: nodeID = " + packet);
}
ReplicationResponseMessageV2 replicationResponseMessage = new ReplicationResponseMessageV2();
if (!started)
return replicationResponseMessage;
if (packet.isSynchronizationFinished()) {
finishSynchronization(packet.getNodeID());
replicationResponseMessage.setSynchronizationIsFinishedAcknowledgement(true);
return replicationResponseMessage;
}
switch(packet.getDataType()) {
case LargeMessages:
for (long msgID : packet.getFileIds()) {
createLargeMessage(msgID, true);
}
break;
case JournalBindings:
case JournalMessages:
if (wantedFailBack && !packet.isServerToFailBack()) {
ActiveMQServerLogger.LOGGER.autoFailBackDenied();
}
final JournalContent journalContent = SyncDataType.getJournalContentType(packet.getDataType());
final Journal journal = journalsHolder.get(journalContent);
if (packet.getNodeID() != null) {
// At the start of replication, we still do not know which is the nodeID that the live uses.
// This is the point where the backup gets this information.
backupQuorum.liveIDSet(packet.getNodeID());
}
Map<Long, JournalSyncFile> mapToFill = filesReservedForSync.get(journalContent);
for (Entry<Long, JournalFile> entry : journal.createFilesForBackupSync(packet.getFileIds()).entrySet()) {
mapToFill.put(entry.getKey(), new JournalSyncFile(entry.getValue()));
}
FileWrapperJournal syncJournal = new FileWrapperJournal(journal);
registerJournal(journalContent.typeByte, syncJournal);
break;
default:
throw ActiveMQMessageBundle.BUNDLE.replicationUnhandledDataType();
}
return replicationResponseMessage;
}
use of org.apache.activemq.artemis.core.journal.Journal in project activemq-artemis by apache.
the class ReplicationEndpoint method finishSynchronization.
private synchronized void finishSynchronization(String liveID) throws Exception {
if (logger.isTraceEnabled()) {
logger.trace("BACKUP-SYNC-START: finishSynchronization::" + liveID);
}
for (JournalContent jc : EnumSet.allOf(JournalContent.class)) {
Journal journal = journalsHolder.remove(jc);
if (logger.isTraceEnabled()) {
logger.trace("getting lock on " + jc + ", journal = " + journal);
}
registerJournal(jc.typeByte, journal);
journal.synchronizationLock();
try {
if (logger.isTraceEnabled()) {
logger.trace("lock acquired on " + jc);
}
// files should be already in place.
filesReservedForSync.remove(jc);
if (logger.isTraceEnabled()) {
logger.trace("stopping journal for " + jc);
}
journal.stop();
if (logger.isTraceEnabled()) {
logger.trace("starting journal for " + jc);
}
journal.start();
if (logger.isTraceEnabled()) {
logger.trace("loadAndSync " + jc);
}
journal.loadSyncOnly(JournalState.SYNCING_UP_TO_DATE);
} finally {
if (logger.isTraceEnabled()) {
logger.trace("unlocking " + jc);
}
journal.synchronizationUnlock();
}
}
if (logger.isTraceEnabled()) {
logger.trace("Sync on large messages...");
}
ByteBuffer buffer = ByteBuffer.allocate(4 * 1024);
for (Entry<Long, ReplicatedLargeMessage> entry : largeMessages.entrySet()) {
ReplicatedLargeMessage lm = entry.getValue();
if (lm instanceof LargeServerMessageInSync) {
LargeServerMessageInSync lmSync = (LargeServerMessageInSync) lm;
if (logger.isTraceEnabled()) {
logger.trace("lmSync on " + lmSync.toString());
}
lmSync.joinSyncedData(buffer);
}
}
if (logger.isTraceEnabled()) {
logger.trace("setRemoteBackupUpToDate and liveIDSet for " + liveID);
}
journalsHolder = null;
backupQuorum.liveIDSet(liveID);
activation.setRemoteBackupUpToDate();
if (logger.isTraceEnabled()) {
logger.trace("Backup is synchronized / BACKUP-SYNC-DONE");
}
ActiveMQServerLogger.LOGGER.backupServerSynched(server);
return;
}
use of org.apache.activemq.artemis.core.journal.Journal in project activemq-artemis by apache.
the class BatchIDGeneratorUnitTest method testSequence.
@Test
public void testSequence() throws Exception {
NIOSequentialFileFactory factory = new NIOSequentialFileFactory(new File(getTestDir()), 1);
Journal journal = new JournalImpl(10 * 1024, 2, 2, 0, 0, factory, "activemq-bindings", "bindings", 1);
journal.start();
journal.load(new ArrayList<RecordInfo>(), new ArrayList<PreparedTransactionInfo>(), null);
BatchingIDGenerator batch = new BatchingIDGenerator(0, 1000, getJournalStorageManager(journal));
long id1 = batch.generateID();
long id2 = batch.generateID();
Assert.assertTrue(id2 > id1);
journal.stop();
batch = new BatchingIDGenerator(0, 1000, getJournalStorageManager(journal));
loadIDs(journal, batch);
long id3 = batch.generateID();
Assert.assertEquals(1001, id3);
long id4 = batch.generateID();
Assert.assertTrue(id4 > id3 && id4 < 2000);
batch.persistCurrentID();
journal.stop();
batch = new BatchingIDGenerator(0, 1000, getJournalStorageManager(journal));
loadIDs(journal, batch);
long id5 = batch.generateID();
Assert.assertTrue(id5 > id4 && id5 < 2000);
long lastId = id5;
boolean close = true;
for (int i = 0; i < 100000; i++) {
if (i % 1000 == 0) {
// interchanging closes and simulated crashes
if (close) {
batch.persistCurrentID();
}
close = !close;
journal.stop();
batch = new BatchingIDGenerator(0, 1000, getJournalStorageManager(journal));
loadIDs(journal, batch);
}
long id = batch.generateID();
Assert.assertTrue(id > lastId);
lastId = id;
}
batch.persistCurrentID();
journal.stop();
batch = new BatchingIDGenerator(0, 1000, getJournalStorageManager(journal));
loadIDs(journal, batch);
lastId = batch.getCurrentID();
journal.stop();
batch = new BatchingIDGenerator(0, 1000, getJournalStorageManager(journal));
loadIDs(journal, batch);
Assert.assertEquals("No Ids were generated, so the currentID was supposed to stay the same", lastId, batch.getCurrentID());
journal.stop();
}
Aggregations