@Override public RefsOperation createRefsOperation(Queue queue) { return new RefsOperation(queue, storageManager); }
@Override public void cancel(final Transaction tx, final MessageReference reference, boolean ignoreRedeliveryCheck) { getRefsOperation(tx, ignoreRedeliveryCheck).addAck(reference); }
@Override public List<MessageReference> getInTXMessagesForConsumer(long consumerId) { if (this.tx != null) { RefsOperation oper = (RefsOperation) tx.getProperty(TransactionPropertyIndexes.REFS_OPERATION); if (oper == null) { return Collections.emptyList(); } else { return oper.getListOnConsumer(consumerId); } } else { //amqp handles the transaction in callback if (callback != null) { Transaction transaction = callback.getCurrentTransaction(); if (transaction != null) { RefsOperation operation = (RefsOperation) transaction.getProperty(TransactionPropertyIndexes.REFS_OPERATION); if (operation != null) { return operation.getListOnConsumer(consumerId); } } } return Collections.emptyList(); } }
@Override public void rollbackRedelivery(Transaction txn, MessageReference ref, long timeBase, Map<QueueImpl, LinkedList<MessageReference>> queueMap) throws Exception { ProtonTransactionImpl tx = (ProtonTransactionImpl) txn; if (tx.getDeliveries().containsKey(ref)) { Delivery del = tx.getDeliveries().get(ref).getA(); ServerConsumer consumer = (ServerConsumer) tx.getDeliveries().get(ref).getB().getBrokerConsumer(); // Rollback normally if the delivery is not settled or a forced TX rollback is done (e.g. connection drop). if (del.remotelySettled() || !tx.isDischarged()) { super.rollbackRedelivery(tx, ref, timeBase, queueMap); } else { ref.incrementDeliveryCount(); consumer.backToDelivering(ref); del.disposition(del.getLocalState() == null ? del.getDefaultDeliveryState() : del.getLocalState()); } } else { super.rollbackRedelivery(tx, ref, timeBase, queueMap); } } }
/** * Openwire will redeliver rolled back references. * We need to return those here. */ private void returnReferences(Transaction tx, AMQSession session) throws Exception { if (session == null || session.isClosed()) { return; } RefsOperation oper = (RefsOperation) tx.getProperty(TransactionPropertyIndexes.REFS_OPERATION); if (oper != null) { List<MessageReference> ackRefs = oper.getReferencesToAcknowledge(); for (ListIterator<MessageReference> referenceIterator = ackRefs.listIterator(ackRefs.size()); referenceIterator.hasPrevious(); ) { MessageReference ref = referenceIterator.previous(); ServerConsumer consumer = null; if (ref.hasConsumerId()) { consumer = session.getCoreSession().locateConsumer(ref.getConsumerId()); } if (consumer != null) { referenceIterator.remove(); ref.incrementDeliveryCount(); consumer.backToDelivering(ref); final AMQConsumer amqConsumer = (AMQConsumer) consumer.getProtocolData(); amqConsumer.addRolledback(ref); } } } }
private RefsOperation getRefsOperation(final Transaction tx, boolean ignoreRedlieveryCheck) { synchronized (tx) { RefsOperation oper = (RefsOperation) tx.getProperty(TransactionPropertyIndexes.REFS_OPERATION); if (oper == null) { oper = tx.createRefsOperation(this); tx.putProperty(TransactionPropertyIndexes.REFS_OPERATION, oper); tx.addOperation(oper); } if (ignoreRedlieveryCheck) { oper.setIgnoreRedeliveryCheck(); } return oper; } }
@Override public void afterCommit(final Transaction tx) { for (MessageReference ref : refsToAck) { synchronized (ref.getQueue()) { queue.postAcknowledge(ref); } } if (pagedMessagesToPostACK != null) { for (MessageReference refmsg : pagedMessagesToPostACK) { ((PagedReference)refmsg).removePendingFlag(); if (((PagedReference) refmsg).isLargeMessage()) { decrementRefCount(refmsg); } } } }
@Override public void rollbackRedelivery(Transaction txn, MessageReference ref, long timeBase, Map<QueueImpl, LinkedList<MessageReference>> queueMap) throws Exception { ProtonTransactionImpl tx = (ProtonTransactionImpl) txn; if (tx.getDeliveries().containsKey(ref)) { Delivery del = tx.getDeliveries().get(ref).getA(); ServerConsumer consumer = (ServerConsumer) tx.getDeliveries().get(ref).getB().getBrokerConsumer(); // Rollback normally if the delivery is not settled or a forced TX rollback is done (e.g. connection drop). if (del.remotelySettled() || !tx.isDischarged()) { super.rollbackRedelivery(tx, ref, timeBase, queueMap); } else { ref.incrementDeliveryCount(); consumer.backToDelivering(ref); del.disposition(del.getLocalState() == null ? del.getDefaultDeliveryState() : del.getLocalState()); } } else { super.rollbackRedelivery(tx, ref, timeBase, queueMap); } } }
List<MessageReference> refs = refsOperation.getReferencesToAcknowledge(); for (MessageReference ref : refs) { Message message = ref.getMessage();
ackedRefs.add(ref); rollbackRedelivery(tx, ref, timeBase, queueMap); } catch (Exception e) { ActiveMQServerLogger.LOGGER.errorCheckingDLQ(e);
@Override public void reacknowledge(final Transaction tx, final MessageReference ref) throws Exception { Message message = ref.getMessage(); if (message.isDurable() && isDurableMessage()) { tx.setContainsPersistent(); } getRefsOperation(tx).addAck(ref); // https://issues.jboss.org/browse/HORNETQ-609 incDelivering(ref); messagesAcknowledged.incrementAndGet(); }
@Override public void acknowledge(final Transaction tx, final MessageReference ref, final AckReason reason, final ServerConsumer consumer) throws Exception { if (ref.isPaged()) { pageSubscription.ackTx(tx, (PagedReference) ref); getRefsOperation(tx).addAck(ref); } else { Message message = ref.getMessage(); boolean durableRef = message.isDurable() && isDurableMessage(); if (durableRef) { storageManager.storeAcknowledgeTransactional(tx.getID(), id, message.getMessageID()); tx.setContainsPersistent(); } getRefsOperation(tx).addAck(ref); } if (reason == AckReason.EXPIRED) { messagesExpired.incrementAndGet(); } else if (reason == AckReason.KILLED) { messagesKilled.incrementAndGet(); } else { messagesAcknowledged.incrementAndGet(); } if (server != null && server.hasBrokerMessagePlugins()) { server.callBrokerMessagePlugins(plugin -> plugin.messageAcknowledged(ref, reason, consumer)); } }