Пример #1
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;
    }
  }