@Override public HandleStatus handle(final MessageReference ref) throws Exception { if (filter != null && !filter.match(ref.getMessage())) { return HandleStatus.NO_MATCH; } synchronized (this) { if (!active || !session.isWritable(this)) { if (logger.isDebugEnabled()) { logger.debug(this + "::Ignoring reference on bridge as it is set to inactive ref=" + ref); } return HandleStatus.BUSY; } if (deliveringLargeMessage) { return HandleStatus.BUSY; } if (logger.isTraceEnabled()) { logger.trace("Bridge " + this + " is handling reference=" + ref); } ref.handled(); synchronized (refs) { refs.put(ref.getMessage().getMessageID(), ref); } final ServerMessage message = beforeForward(ref.getMessage()); final SimpleString dest; if (forwardingAddress != null) { dest = forwardingAddress; } else { // Preserve the original address dest = message.getAddress(); } pendingAcks.countUp(); try { if (message.isLargeMessage()) { deliveringLargeMessage = true; deliverLargeMessage(dest, ref, (LargeServerMessage) message); return HandleStatus.HANDLED; } else { return deliverStandardMessage(dest, ref, message); } } catch (Exception e) { // If an exception happened, we must count down immediately pendingAcks.countDown(); throw e; } } }
@Override public boolean page( ServerMessage message, final Transaction tx, RouteContextList listCtx, final ReadLock managerLock) throws Exception { if (!running) { throw new IllegalStateException("PagingStore(" + getStoreName() + ") not initialized"); } boolean full = isFull(); if (addressFullMessagePolicy == AddressFullMessagePolicy.DROP || addressFullMessagePolicy == AddressFullMessagePolicy.FAIL) { if (full) { if (!printedDropMessagesWarning) { printedDropMessagesWarning = true; ActiveMQServerLogger.LOGGER.pageStoreDropMessages(storeName, sizeInBytes.get(), maxSize); } if (message.isLargeMessage()) { ((LargeServerMessage) message).deleteFile(); } if (addressFullMessagePolicy == AddressFullMessagePolicy.FAIL) { throw ActiveMQMessageBundle.BUNDLE.addressIsFull(address.toString()); } // Address is full, we just pretend we are paging, and drop the data return true; } else { return false; } } else if (addressFullMessagePolicy == AddressFullMessagePolicy.BLOCK) { return false; } // We need to ensure a read lock, as depage could change the paging state lock.readLock().lock(); try { // First check done concurrently, to avoid synchronization and increase throughput if (!paging) { return false; } } finally { lock.readLock().unlock(); } managerLock.lock(); try { lock.writeLock().lock(); try { if (!paging) { return false; } if (!message.isDurable()) { // The address should never be transient when paging (even for non-persistent messages // when paging) // This will force everything to be persisted message.forceAddress(address); } final long transactionID = tx == null ? -1 : tx.getID(); PagedMessage pagedMessage = new PagedMessageImpl(message, routeQueues(tx, listCtx), transactionID); if (message.isLargeMessage()) { ((LargeServerMessage) message).setPaged(); } int bytesToWrite = pagedMessage.getEncodeSize() + Page.SIZE_RECORD; if (currentPageSize.addAndGet(bytesToWrite) > pageSize && currentPage.getNumberOfMessages() > 0) { // Make sure nothing is currently validating or using currentPage openNewPage(); currentPageSize.addAndGet(bytesToWrite); } if (tx != null) { installPageTransaction(tx, listCtx); } // the apply counter will make sure we write a record on journal // especially on the case for non transactional sends and paging // doing this will give us a possibility of recovering the page counters applyPageCounters(tx, getCurrentPage(), listCtx); currentPage.write(pagedMessage); if (tx == null && syncNonTransactional && message.isDurable()) { sync(); } if (isTrace) { ActiveMQServerLogger.LOGGER.trace( "Paging message " + pagedMessage + " on pageStore " + this.getStoreName() + " pageId=" + currentPage.getPageId()); } return true; } finally { lock.writeLock().unlock(); } } finally { managerLock.unlock(); } }