use of org.apache.activemq.artemis.core.replication.ReplicatedJournal in project activemq-artemis by apache.
the class JournalStorageManager method startReplication.
@Override
public void startReplication(ReplicationManager replicationManager, PagingManager pagingManager, String nodeID, final boolean autoFailBack, long initialReplicationSyncTimeout) throws Exception {
if (!started) {
throw new IllegalStateException("JournalStorageManager must be started...");
}
assert replicationManager != null;
if (!(messageJournal instanceof JournalImpl) || !(bindingsJournal instanceof JournalImpl)) {
throw ActiveMQMessageBundle.BUNDLE.notJournalImpl();
}
// We first do a compact without any locks, to avoid copying unnecessary data over the network.
// We do this without holding the storageManager lock, so the journal stays open while compact is being done
originalMessageJournal.scheduleCompactAndBlock(-1);
originalBindingsJournal.scheduleCompactAndBlock(-1);
JournalFile[] messageFiles = null;
JournalFile[] bindingsFiles = null;
// We get a picture of the current sitaution on the large messages
// and we send the current messages while more state is coming
Map<Long, Pair<String, Long>> pendingLargeMessages = null;
try {
Map<SimpleString, Collection<Integer>> pageFilesToSync;
storageManagerLock.writeLock().lock();
try {
if (isReplicated())
throw new ActiveMQIllegalStateException("already replicating");
replicator = replicationManager;
if (!((JournalImpl) originalMessageJournal).flushAppendExecutor(10, TimeUnit.SECONDS)) {
throw new Exception("Live message journal is busy");
}
if (!((JournalImpl) originalBindingsJournal).flushAppendExecutor(10, TimeUnit.SECONDS)) {
throw new Exception("Live bindings journal is busy");
}
// Establishes lock
originalMessageJournal.synchronizationLock();
originalBindingsJournal.synchronizationLock();
try {
originalBindingsJournal.replicationSyncPreserveOldFiles();
originalMessageJournal.replicationSyncPreserveOldFiles();
pagingManager.lock();
try {
pagingManager.disableCleanup();
messageFiles = prepareJournalForCopy(originalMessageJournal, JournalContent.MESSAGES, nodeID, autoFailBack);
bindingsFiles = prepareJournalForCopy(originalBindingsJournal, JournalContent.BINDINGS, nodeID, autoFailBack);
pageFilesToSync = getPageInformationForSync(pagingManager);
pendingLargeMessages = recoverPendingLargeMessages();
} finally {
pagingManager.unlock();
}
} finally {
originalMessageJournal.synchronizationUnlock();
originalBindingsJournal.synchronizationUnlock();
}
bindingsJournal = new ReplicatedJournal(((byte) 0), originalBindingsJournal, replicator);
messageJournal = new ReplicatedJournal((byte) 1, originalMessageJournal, replicator);
// We need to send the list while locking otherwise part of the body might get sent too soon
// it will send a list of IDs that we are allocating
replicator.sendLargeMessageIdListMessage(pendingLargeMessages);
} finally {
storageManagerLock.writeLock().unlock();
}
sendJournalFile(messageFiles, JournalContent.MESSAGES);
sendJournalFile(bindingsFiles, JournalContent.BINDINGS);
sendLargeMessageFiles(pendingLargeMessages);
sendPagesToBackup(pageFilesToSync, pagingManager);
storageManagerLock.writeLock().lock();
try {
if (replicator != null) {
replicator.sendSynchronizationDone(nodeID, initialReplicationSyncTimeout);
performCachedLargeMessageDeletes();
}
} finally {
storageManagerLock.writeLock().unlock();
}
} catch (Exception e) {
ActiveMQServerLogger.LOGGER.unableToStartReplication(e);
stopReplication();
throw e;
} finally {
// Re-enable compact and reclaim of journal files
originalBindingsJournal.replicationSyncFinished();
originalMessageJournal.replicationSyncFinished();
pagingManager.resumeCleanup();
}
}
use of org.apache.activemq.artemis.core.replication.ReplicatedJournal in project activemq-artemis by apache.
the class ReplicationTest method testSendPackets.
@Test
public void testSendPackets() throws Exception {
setupServer(true);
JournalStorageManager storage = getStorage();
manager = liveServer.getReplicationManager();
waitForComponent(manager);
Journal replicatedJournal = new ReplicatedJournal((byte) 1, new FakeJournal(), manager);
replicatedJournal.appendPrepareRecord(1, new FakeData(), false);
replicatedJournal.appendAddRecord(1, (byte) 1, new FakeData(), false);
replicatedJournal.appendUpdateRecord(1, (byte) 2, new FakeData(), false);
replicatedJournal.appendDeleteRecord(1, false);
replicatedJournal.appendAddRecordTransactional(2, 2, (byte) 1, new FakeData());
replicatedJournal.appendUpdateRecordTransactional(2, 2, (byte) 2, new FakeData());
replicatedJournal.appendCommitRecord(2, false);
replicatedJournal.appendDeleteRecordTransactional(3, 4, new FakeData());
replicatedJournal.appendPrepareRecord(3, new FakeData(), false);
replicatedJournal.appendRollbackRecord(3, false);
blockOnReplication(storage, manager);
Assert.assertTrue("Expecting no active tokens:" + manager.getActiveTokens(), manager.getActiveTokens().isEmpty());
CoreMessage msg = new CoreMessage().initBuffer(1024).setMessageID(1);
SimpleString dummy = new SimpleString("dummy");
msg.setAddress(dummy);
replicatedJournal.appendAddRecordTransactional(23, 24, (byte) 1, new FakeData());
PagedMessage pgmsg = new PagedMessageImpl(msg, new long[0]);
manager.pageWrite(pgmsg, 1);
manager.pageWrite(pgmsg, 2);
manager.pageWrite(pgmsg, 3);
manager.pageWrite(pgmsg, 4);
blockOnReplication(storage, manager);
PagingManager pagingManager = createPageManager(backupServer.getStorageManager(), backupServer.getConfiguration(), backupServer.getExecutorFactory(), backupServer.getAddressSettingsRepository());
PagingStore store = pagingManager.getPageStore(dummy);
store.start();
Assert.assertEquals(4, store.getNumberOfPages());
store.stop();
manager.pageDeleted(dummy, 1);
manager.pageDeleted(dummy, 2);
manager.pageDeleted(dummy, 3);
manager.pageDeleted(dummy, 4);
manager.pageDeleted(dummy, 5);
manager.pageDeleted(dummy, 6);
blockOnReplication(storage, manager);
CoreMessage serverMsg = new CoreMessage();
serverMsg.setMessageID(500);
serverMsg.setAddress(new SimpleString("tttt"));
ActiveMQBuffer buffer = ActiveMQBuffers.dynamicBuffer(100);
serverMsg.encodeHeadersAndProperties(buffer.byteBuf());
manager.largeMessageBegin(500);
manager.largeMessageWrite(500, new byte[1024]);
manager.largeMessageDelete(Long.valueOf(500), storage);
blockOnReplication(storage, manager);
store.start();
Assert.assertEquals(0, store.getNumberOfPages());
}
use of org.apache.activemq.artemis.core.replication.ReplicatedJournal in project activemq-artemis by apache.
the class ReplicationTest method testNoActions.
@Test
public void testNoActions() throws Exception {
setupServer(true);
StorageManager storage = getStorage();
manager = liveServer.getReplicationManager();
waitForComponent(manager);
Journal replicatedJournal = new ReplicatedJournal((byte) 1, new FakeJournal(), manager);
replicatedJournal.appendPrepareRecord(1, new FakeData(), false);
final CountDownLatch latch = new CountDownLatch(1);
storage.afterCompleteOperations(new IOCallback() {
@Override
public void onError(final int errorCode, final String errorMessage) {
}
@Override
public void done() {
latch.countDown();
}
});
Assert.assertTrue(latch.await(1, TimeUnit.SECONDS));
Assert.assertEquals("should be empty " + manager.getActiveTokens(), 0, manager.getActiveTokens().size());
}
use of org.apache.activemq.artemis.core.replication.ReplicatedJournal in project activemq-artemis by apache.
the class ReplicationTest method testOrderOnNonPersistency.
@Test
public void testOrderOnNonPersistency() throws Exception {
setupServer(true);
final ArrayList<Integer> executions = new ArrayList<>();
StorageManager storage = getStorage();
manager = liveServer.getReplicationManager();
Journal replicatedJournal = new ReplicatedJournal((byte) 1, new FakeJournal(), manager);
int numberOfAdds = 200;
final CountDownLatch latch = new CountDownLatch(numberOfAdds);
OperationContext ctx = storage.getContext();
for (int i = 0; i < numberOfAdds; i++) {
final int nAdd = i;
if (i % 2 == 0) {
replicatedJournal.appendPrepareRecord(i, new FakeData(), false);
}
ctx.executeOnCompletion(new IOCallback() {
@Override
public void onError(final int errorCode, final String errorMessage) {
}
@Override
public void done() {
executions.add(nAdd);
latch.countDown();
}
});
}
Assert.assertTrue(latch.await(10, TimeUnit.SECONDS));
for (int i = 0; i < numberOfAdds; i++) {
Assert.assertEquals(i, executions.get(i).intValue());
}
Assert.assertEquals(0, manager.getActiveTokens().size());
}
Aggregations