private void finishSynchronization(String liveID) throws Exception { for (JournalContent jc : EnumSet.allOf(JournalContent.class)) { Journal journal = journalsHolder.remove(jc); journal.synchronizationLock(); try { // files should be already in place. filesReservedForSync.remove(jc); registerJournal(jc.typeByte, journal); journal.stop(); journal.start(); journal.loadSyncOnly(JournalState.SYNCING_UP_TO_DATE); } finally { journal.synchronizationUnlock(); } } 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; lmSync.joinSyncedData(buffer); } } journalsHolder = null; backupQuorum.liveIDSet(liveID); activation.setRemoteBackupUpToDate(); ActiveMQServerLogger.LOGGER.backupServerSynched(server); return; }
/** * 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 * @throws Exception * @return if the incoming packet indicates the synchronization is finished then return an * acknowledgement otherwise return an empty response */ private ReplicationResponseMessageV2 handleStartReplicationSynchronization( final ReplicationStartSyncMessage packet) throws Exception { ReplicationResponseMessageV2 replicationResponseMessage = new ReplicationResponseMessageV2(); if (activation.isRemoteBackupUpToDate()) { throw ActiveMQMessageBundle.BUNDLE.replicationBackupUpToDate(); } synchronized (this) { 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; }