Пример #1
0
  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);
                  }
                }
              });
    }
  }
Пример #2
0
 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()));
 }
Пример #3
0
  /**
   * 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();
                }
              });
    }
  }
Пример #4
0
 @Override
 public void setBatch(MessageId messageId) throws Exception {
   peristenceAdapter.checkpoint(true, true);
   longTermStore.setBatch(messageId);
 }
Пример #5
0
 public void recoverNextMessages(int maxReturned, MessageRecoveryListener listener)
     throws Exception {
   peristenceAdapter.checkpoint(true, true);
   longTermStore.recoverNextMessages(maxReturned, listener);
 }
Пример #6
0
 public long getMessageSize() throws IOException {
   peristenceAdapter.checkpoint(true, true);
   return longTermStore.getMessageSize();
 }
Пример #7
0
 /** @see org.apache.activemq.store.MessageStore#removeAllMessages(ConnectionContext) */
 public void removeAllMessages(ConnectionContext context) throws IOException {
   peristenceAdapter.checkpoint(true, true);
   longTermStore.removeAllMessages(context);
 }
Пример #8
0
 /**
  * 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);
 }
Пример #9
0
  /**
   * @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;
    }
  }