public void removeMessage(ConnectionContext context, final MessageAck ack) throws IOException { final boolean debug = LOG.isDebugEnabled(); JournalQueueAck remove = new JournalQueueAck(); remove.setDestination(destination); remove.setMessageAck(ack); final RecordLocation location = peristenceAdapter.writeCommand(remove, ack.isResponseRequired()); if (!context.isInTransaction()) { if (debug) { LOG.debug("Journalled message remove for: " + ack.getLastMessageId() + ", at: " + location); } removeMessage(ack, location); } else { if (debug) { LOG.debug( "Journalled transacted message remove for: " + ack.getLastMessageId() + ", at: " + location); } synchronized (this) { inFlightTxLocations.add(location); } transactionStore.removeMessage(this, ack, location); context .getTransaction() .addSynchronization( new Synchronization() { public void afterCommit() throws Exception { if (debug) { LOG.debug( "Transacted message remove commit for: " + ack.getLastMessageId() + ", at: " + location); } synchronized (JournalMessageStore.this) { inFlightTxLocations.remove(location); removeMessage(ack, location); } } public void afterRollback() throws Exception { if (debug) { LOG.debug( "Transacted message remove rollback for: " + ack.getLastMessageId() + ", at: " + location); } synchronized (JournalMessageStore.this) { inFlightTxLocations.remove(location); } } }); } }
public JournalMessageStore( JournalPersistenceAdapter adapter, MessageStore checkpointStore, ActiveMQDestination destination) { super(destination); this.peristenceAdapter = adapter; this.transactionStore = adapter.getTransactionStore(); this.longTermStore = checkpointStore; this.transactionTemplate = new TransactionTemplate( adapter, new ConnectionContext(new NonCachedMessageEvaluationContext())); }
/** * Not synchronized since the Journal has better throughput if you increase the number of * concurrent writes that it is doing. */ public void addMessage(final ConnectionContext context, final Message message) throws IOException { final MessageId id = message.getMessageId(); final boolean debug = LOG.isDebugEnabled(); message.incrementReferenceCount(); final RecordLocation location = peristenceAdapter.writeCommand(message, message.isResponseRequired()); if (!context.isInTransaction()) { if (debug) { LOG.debug("Journalled message add for: " + id + ", at: " + location); } addMessage(context, message, location); } else { if (debug) { LOG.debug("Journalled transacted message add for: " + id + ", at: " + location); } synchronized (this) { inFlightTxLocations.add(location); } transactionStore.addMessage(this, message, location); context .getTransaction() .addSynchronization( new Synchronization() { public void afterCommit() throws Exception { if (debug) { LOG.debug("Transacted message add commit for: " + id + ", at: " + location); } synchronized (JournalMessageStore.this) { inFlightTxLocations.remove(location); addMessage(context, message, location); } } public void afterRollback() throws Exception { if (debug) { LOG.debug("Transacted message add rollback for: " + id + ", at: " + location); } synchronized (JournalMessageStore.this) { inFlightTxLocations.remove(location); } message.decrementReferenceCount(); } }); } }
@Override public void setBatch(MessageId messageId) throws Exception { peristenceAdapter.checkpoint(true, true); longTermStore.setBatch(messageId); }
public void recoverNextMessages(int maxReturned, MessageRecoveryListener listener) throws Exception { peristenceAdapter.checkpoint(true, true); longTermStore.recoverNextMessages(maxReturned, listener); }
public long getMessageSize() throws IOException { peristenceAdapter.checkpoint(true, true); return longTermStore.getMessageSize(); }
/** @see org.apache.activemq.store.MessageStore#removeAllMessages(ConnectionContext) */ public void removeAllMessages(ConnectionContext context) throws IOException { peristenceAdapter.checkpoint(true, true); longTermStore.removeAllMessages(context); }
/** * Replays the checkpointStore first as those messages are the oldest ones, then messages are * replayed from the transaction log and then the cache is updated. * * @param listener * @throws Exception */ public void recover(final MessageRecoveryListener listener) throws Exception { peristenceAdapter.checkpoint(true, true); longTermStore.recover(listener); }
/** * @return * @throws IOException */ @SuppressWarnings("unchecked") public RecordLocation checkpoint(final Callback postCheckpointTest) throws IOException { final List<MessageAck> cpRemovedMessageLocations; final List<RecordLocation> cpActiveJournalLocations; final int maxCheckpointMessageAddSize = peristenceAdapter.getMaxCheckpointMessageAddSize(); // swap out the message hash maps.. synchronized (this) { cpAddedMessageIds = this.messages; cpRemovedMessageLocations = this.messageAcks; cpActiveJournalLocations = new ArrayList<RecordLocation>(inFlightTxLocations); this.messages = new LinkedHashMap<MessageId, Message>(); this.messageAcks = new ArrayList<MessageAck>(); } transactionTemplate.run( new Callback() { public void execute() throws Exception { int size = 0; PersistenceAdapter persitanceAdapter = transactionTemplate.getPersistenceAdapter(); ConnectionContext context = transactionTemplate.getContext(); // Checkpoint the added messages. synchronized (JournalMessageStore.this) { Iterator<Message> iterator = cpAddedMessageIds.values().iterator(); while (iterator.hasNext()) { Message message = iterator.next(); try { longTermStore.addMessage(context, message); } catch (Throwable e) { LOG.warn("Message could not be added to long term store: " + e.getMessage(), e); } size += message.getSize(); message.decrementReferenceCount(); // Commit the batch if it's getting too big if (size >= maxCheckpointMessageAddSize) { persitanceAdapter.commitTransaction(context); persitanceAdapter.beginTransaction(context); size = 0; } } } persitanceAdapter.commitTransaction(context); persitanceAdapter.beginTransaction(context); // Checkpoint the removed messages. Iterator<MessageAck> iterator = cpRemovedMessageLocations.iterator(); while (iterator.hasNext()) { try { MessageAck ack = iterator.next(); longTermStore.removeMessage(transactionTemplate.getContext(), ack); } catch (Throwable e) { LOG.debug( "Message could not be removed from long term store: " + e.getMessage(), e); } } if (postCheckpointTest != null) { postCheckpointTest.execute(); } } }); synchronized (this) { cpAddedMessageIds = null; } if (cpActiveJournalLocations.size() > 0) { Collections.sort(cpActiveJournalLocations); return cpActiveJournalLocations.get(0); } synchronized (this) { return lastLocation; } }