public DispatchedNode(final MessageReference node) { super(); this.size = node.getSize(); this.messageId = node.getMessageId(); this.destination = node.getRegionDestination() instanceof Destination ? ((Destination)node.getRegionDestination()) : null; }
@Override public synchronized List<MessageReference> remove(ConnectionContext context, Destination destination) throws Exception { List<MessageReference> rc = new ArrayList<MessageReference>(); for (Iterator<MessageReference> iterator = list.iterator(); iterator.hasNext();) { MessageReference r = iterator.next(); if (r.getRegionDestination() == destination) { r.decrementReferenceCount(); rc.add(r); iterator.remove(); } } return rc; }
/** * In the queue case, mark the node as dropped and then a gc cycle will * remove it from the queue. * * @throws IOException */ @Override protected void acknowledge(final ConnectionContext context, final MessageAck ack, final MessageReference n) throws IOException { this.setTimeOfLastMessageAck(System.currentTimeMillis()); final Destination q = (Destination) n.getRegionDestination(); final QueueMessageReference node = (QueueMessageReference)n; final Queue queue = (Queue)q; queue.removeMessage(context, this, node, ack); }
private void addReferencesAndUpdateRedispatch(LinkedList<MessageReference> redispatch, Destination destination, List<MessageReference> dispatched) { ArrayList<MessageReference> references = new ArrayList<MessageReference>(); for (MessageReference r : dispatched) { if (r.getRegionDestination() == destination) { references.add(r); getSubscriptionStatistics().getInflightMessageSize().addSize(-r.getSize()); } } redispatch.addAll(0, references); destination.getDestinationStatistics().getInflight().subtract(references.size()); dispatched.removeAll(references); }
@Override protected void acknowledge(ConnectionContext context, MessageAck ack, MessageReference node) throws IOException { this.setTimeOfLastMessageAck(System.currentTimeMillis()); Destination regionDestination = (Destination) node.getRegionDestination(); regionDestination.acknowledge(context, this, ack, node); redeliveredMessages.remove(node.getMessageId()); node.decrementReferenceCount(); ((Destination)node.getRegionDestination()).getDestinationStatistics().getDequeues().increment(); if (info.isNetworkSubscription()) { ((Destination)node.getRegionDestination()).getDestinationStatistics().getForwards().add(ack.getMessageCount()); } }
@Override public void add(MessageReference node) throws Exception { synchronized (pendingLock) { // The destination may have just been removed... if (!destinations.contains(node.getRegionDestination()) && node != QueueMessageReference.NULL_MESSAGE) { // perhaps we should inform the caller that we are no longer valid to dispatch to? return; } // Don't increment for the pullTimeout control message. if (!node.equals(QueueMessageReference.NULL_MESSAGE)) { getSubscriptionStatistics().getEnqueues().increment(); } pending.addMessageLast(node); } dispatchPending(); }
private void discardExpiredMessage(MessageReference reference) { LOG.debug("Discarding expired message {}", reference); if (reference.isExpired() && broker.isExpired(reference)) { ConnectionContext context = new ConnectionContext(); context.setBroker(broker); ((Destination)reference.getRegionDestination()).messageExpired(context, null, new IndirectMessageReference(reference.getMessage())); } }
/** * store will have a pending ack for all durables, irrespective of the * selector so we need to ack if node is un-matched */ @Override public void unmatched(MessageReference node) throws IOException { MessageAck ack = new MessageAck(); ack.setAckType(MessageAck.UNMATCHED_ACK_TYPE); ack.setMessageID(node.getMessageId()); Destination regionDestination = (Destination) node.getRegionDestination(); regionDestination.acknowledge(this.getContext(), this, ack, node); }
} else { try { Destination regionDestination = (Destination) messageReference.getRegionDestination(); final RedeliveryPolicy redeliveryPolicy = redeliveryPolicyMap.getEntryFor(regionDestination.getActiveMQDestination()); if (redeliveryPolicy != null) {
@Override public void onSuccess() { Destination regionDestination = (Destination) node.getRegionDestination(); regionDestination.getDestinationStatistics().getDispatched().increment(); regionDestination.getDestinationStatistics().getInflight().increment(); node.decrementReferenceCount(); }
@Override public void onFailure() { Destination regionDestination = (Destination) node.getRegionDestination(); regionDestination.getDestinationStatistics().getDispatched().increment(); regionDestination.getDestinationStatistics().getInflight().increment(); node.decrementReferenceCount(); } });
private void discard(MessageReference message) { discarding = true; try { message.decrementReferenceCount(); matched.remove(message); discarded++; if (destination != null) { destination.getDestinationStatistics().getDequeues().increment(); } LOG.debug("{}, discarding message {}", this, message); Destination dest = (Destination) message.getRegionDestination(); if (dest != null) { dest.messageDiscarded(getContext(), this, message); } broker.getRoot().sendToDeadLetterQueue(getContext(), message, this, new Throwable("TopicSubDiscard. ID:" + info.getConsumerId())); } finally { discarding = false; } }
@Override public void onFailure() { Destination nodeDest = (Destination) node.getRegionDestination(); if (nodeDest != null) { if (node != QueueMessageReference.NULL_MESSAGE) { nodeDest.getDestinationStatistics().getDispatched().increment(); nodeDest.getDestinationStatistics().getInflight().increment(); LOG.trace("{} failed to dispatch: {} - {}, dispatched: {}, inflight: {}", new Object[]{ info.getConsumerId(), message.getMessageId(), message.getDestination(), getSubscriptionStatistics().getDispatched().getCount(), dispatched.size() }); } } if (node instanceof QueueMessageReference) { ((QueueMessageReference) node).unlock(); } } });
@Override public boolean addRecoveredMessage(ConnectionContext context, MessageReference message) throws Exception { boolean result = false; MessageEvaluationContext msgContext = context.getMessageEvaluationContext(); try { Destination regionDestination = (Destination) message.getRegionDestination(); msgContext.setDestination(regionDestination.getActiveMQDestination()); msgContext.setMessageReference(message); result = matches(message, msgContext); if (result) { doAddRecoveredMessage(message); } } finally { msgContext.clear(); } return result; }
protected void onDispatch(final MessageReference node, final Message message) { Destination nodeDest = (Destination) node.getRegionDestination(); if (nodeDest != null) { if (node != QueueMessageReference.NULL_MESSAGE) { nodeDest.getDestinationStatistics().getDispatched().increment(); nodeDest.getDestinationStatistics().getInflight().increment(); LOG.trace("{} dispatched: {} - {}, dispatched: {}, inflight: {}", new Object[]{ info.getConsumerId(), message.getMessageId(), message.getDestination(), getSubscriptionStatistics().getDispatched().getCount(), dispatched.size() }); } } if (info.isDispatchAsync()) { try { dispatchPending(); } catch (IOException e) { context.getConnection().serviceExceptionAsync(e); } } }
private boolean hasNoLocalConsumers(final Message message, final MessageEvaluationContext mec) { Destination regionDestination = (Destination) mec.getMessageReference().getRegionDestination(); List<Subscription> consumers = regionDestination.getConsumers(); for (Subscription sub : consumers) { if (!sub.getConsumerInfo().isNetworkSubscription() && !sub.getConsumerInfo().isBrowser()) { if (!isSelectorAware()) { LOG.trace("Not replaying [{}] for [{}] to origin due to existing local consumer: {}", new Object[]{ message.getMessageId(), message.getDestination(), sub.getConsumerInfo() }); return false; } else { try { if (sub.matches(message, mec)) { LOG.trace("Not replaying [{}] for [{}] to origin due to existing selector matching local consumer: {}", new Object[]{ message.getMessageId(), message.getDestination(), sub.getConsumerInfo() }); return false; } } catch (Exception ignored) {} } } } return true; }
@Override public void afterCommit() throws Exception { Destination nodeDest = (Destination) node.getRegionDestination(); synchronized (dispatchLock) { getSubscriptionStatistics().getDequeues().increment(); if (dispatched.remove(node)) { // if consumer is removed, dispatched will be empty and inflight will // already have been adjusted getSubscriptionStatistics().getInflightMessageSize().addSize(-node.getSize()); nodeDest.getDestinationStatistics().getInflight().decrement(); } } contractPrefetchExtension(1); nodeDest.wakeup(); dispatchPending(); }
/** * @param node * @param message * @return MessageDispatch */ protected MessageDispatch createMessageDispatch(MessageReference node, Message message) { MessageDispatch md = new MessageDispatch(); md.setConsumerId(info.getConsumerId()); if (node == QueueMessageReference.NULL_MESSAGE) { md.setMessage(null); md.setDestination(null); } else { Destination regionDestination = (Destination) node.getRegionDestination(); md.setDestination(regionDestination.getActiveMQDestination()); md.setMessage(message); md.setRedeliveryCounter(node.getRedeliveryCounter()); } return md; }
private void scheduleRedelivery(ConnectionContext context, MessageReference messageReference, long delay, int redeliveryCount) throws Exception { if (LOG.isTraceEnabled()) { Destination regionDestination = (Destination) messageReference.getRegionDestination(); LOG.trace("redelivery #{} of: {} with delay: {}, dest: {}", new Object[]{ redeliveryCount, messageReference.getMessageId(), delay, regionDestination.getActiveMQDestination() }); } final Message old = messageReference.getMessage(); Message message = old.copy(); message.setTransactionId(null); message.setMemoryUsage(null); message.removeProperty(ScheduledMessage.AMQ_SCHEDULED_ID); message.setProperty(REDELIVERY_DELAY, delay); message.setProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, delay); message.setRedeliveryCounter(redeliveryCount); boolean originalFlowControl = context.isProducerFlowControl(); try { context.setProducerFlowControl(false); ProducerInfo info = new ProducerInfo(); ProducerState state = new ProducerState(info); ProducerBrokerExchange producerExchange = new ProducerBrokerExchange(); producerExchange.setProducerState(state); producerExchange.setMutable(true); producerExchange.setConnectionContext(context); context.getBroker().send(producerExchange, message); } finally { context.setProducerFlowControl(originalFlowControl); } }
/** * Discard any expired messages from the matched list. Called from a * synchronized block. * * @throws IOException */ protected void removeExpiredMessages() throws IOException { try { matched.reset(); while (matched.hasNext()) { MessageReference node = matched.next(); node.decrementReferenceCount(); if (node.isExpired()) { matched.remove(); node.decrementReferenceCount(); if (broker.isExpired(node)) { ((Destination) node.getRegionDestination()).getDestinationStatistics().getExpired().increment(); broker.messageExpired(getContext(), node, this); } break; } } } finally { matched.release(); } }