public boolean dispatch(MessageReference node, MessageEvaluationContext msgContext, List<Subscription> consumers) throws Exception { int count = 0; for (Subscription sub : consumers) { // Don't deliver to browsers if (sub.getConsumerInfo().isBrowser()) { continue; } // Only dispatch to interested subscriptions if (!sub.matches(node, msgContext)) { sub.unmatched(node); continue; } sub.add(node); count++; } return count > 0; }
public void unregisterSubscription(Subscription sub) { ObjectName name = subscriptionMap.remove(sub); if (name != null) { try { SubscriptionKey subscriptionKey = new SubscriptionKey(sub.getContext().getClientId(), sub.getConsumerInfo().getSubscriptionName()); ObjectName inactiveName = subscriptionKeys.remove(subscriptionKey); if (inactiveName != null) { inactiveDurableTopicSubscribers.remove(inactiveName); managementContext.unregisterMBean(inactiveName); } } catch (Exception e) { LOG.error("Failed to unregister subscription {}", sub, e); } } }
@Override public void removeSubscription(ConnectionContext context, Subscription sub, long lastDeliveredSequenceId) throws Exception { if (!sub.getConsumerInfo().isDurable()) { boolean removed = false; synchronized (consumers) { removed = consumers.remove(sub); } if (removed) { super.removeSubscription(context, sub, lastDeliveredSequenceId); } } sub.remove(context, this); }
private int getConsumerMessageCountBeforeFull() throws Exception { int total = 0; consumersLock.readLock().lock(); try { for (Subscription s : consumers) { if (s.isBrowser()) { continue; } int countBeforeFull = s.countBeforeFull(); total += countBeforeFull; } } finally { consumersLock.readLock().unlock(); } return total; }
/** * @param node * @param msgContext * @param consumers * @return true if dispatched * @throws Exception * @see org.apache.activemq.broker.region.policy.DispatchPolicy#dispatch(org.apache.activemq.broker.region.MessageReference, * org.apache.activemq.filter.MessageEvaluationContext, java.util.List) */ public boolean dispatch(MessageReference node, MessageEvaluationContext msgContext, List consumers) throws Exception { // Big synch here so that only 1 message gets dispatched at a time. // Ensures // Everyone sees the same order. synchronized (consumers) { int count = 0; for (Iterator iter = consumers.iterator(); iter.hasNext();) { Subscription sub = (Subscription)iter.next(); // Only dispatch to interested subscriptions if (!sub.matches(node, msgContext)) { sub.unmatched(node); continue; } sub.add(node); count++; } return count > 0; } }
int match = sub.getActiveMQDestination().compareTo(next.getActiveMQDestination()); if (match == 0 || (!next.getActiveMQDestination().isPattern() && match == 1)) { super.addSubscription(context, sub); final Set<Destination> virtualDests = regionBroker.getDestinations(virtualDestination); final ActiveMQDestination newDestination = sub.getActiveMQDestination(); BaseDestination regionDest = null; (virtualDest.isAlwaysRetroactive() || sub.getConsumerInfo().isRetroactive())) { sub.addRecoveredMessage(context, newDestination.isQueue() ? new IndirectMessageReference(copy) : copy);
private void updateSlowConsumersList(List<Subscription> subscribers) { for (Subscription subscriber : subscribers) { if (isIgnoreNetworkSubscriptions() && subscriber.getConsumerInfo().isNetworkSubscription()) { if (slowConsumers.remove(subscriber) != null) { LOG.info("network sub: {} is no longer slow", subscriber.getConsumerInfo().getConsumerId()); if (isIgnoreIdleConsumers() && subscriber.getDispatchedQueueSize() == 0) { LOG.info("idle sub: {} is no longer slow", subscriber.getConsumerInfo().getConsumerId()); long lastAckTime = subscriber.getTimeOfLastMessageAck(); long timeDelta = System.currentTimeMillis() - lastAckTime; LOG.debug("sub: {} is now slow", subscriber.getConsumerInfo().getConsumerId()); SlowConsumerEntry entry = new SlowConsumerEntry(subscriber.getContext()); LOG.info("sub: {} is no longer slow", subscriber.getConsumerInfo().getConsumerId());
@Override public int compare(Subscription o1, Subscription o2) { // We want the list sorted in descending order return o2.getConsumerInfo().getPriority() - o1.getConsumerInfo().getPriority(); } };
@Override public void processDispatchNotification(MessageDispatchNotification messageDispatchNotification) throws Exception { // do dispatch Subscription sub = getMatchingSubscription(messageDispatchNotification); if (sub != null) { MessageReference message = getMatchingMessage(messageDispatchNotification); sub.add(message); sub.processMessageDispatchNotification(messageDispatchNotification); } }
if (!s.isFull()) { if (dispatchSelector.canSelect(s, node) && assignMessageGroup(s, (QueueMessageReference)node) && !((QueueMessageReference) node).isAcked() ) { s.add(node); LOG.trace("assigned {} to consumer {}", node.getMessageId(), s.getConsumerInfo().getConsumerId()); iterator.remove(); target = s;
protected List<Subscription> addSubscriptionsForDestination(ConnectionContext context, Destination dest) throws Exception { List<Subscription> rc = new ArrayList<Subscription>(); // Add all consumers that are interested in the destination. for (Iterator<Subscription> iter = subscriptions.values().iterator(); iter.hasNext();) { Subscription sub = iter.next(); if (sub.matches(dest.getActiveMQDestination())) { try { ConnectionContext originalContext = sub.getContext() != null ? sub.getContext() : context; dest.addSubscription(originalContext, sub); rc.add(sub); } catch (SecurityException e) { if (sub.isWildcard()) { LOG.debug("Subscription denied for " + sub + " to destination " + dest.getActiveMQDestination() + ": " + e.getMessage()); } else { throw e; } } } } return rc; }
@Override public void addSubscription(ConnectionContext context, final Subscription sub) throws Exception { if (!sub.getConsumerInfo().isDurable()) { if (sub.getConsumerInfo().isRetroactive() || isAlwaysRetroactive()) { synchronized (consumers) { if (!consumers.contains(sub)){ sub.add(context, this); consumers.add(sub); applyRecovery=true; synchronized (consumers) { if (!consumers.contains(sub)){ sub.add(context, this); consumers.add(sub); super.addSubscription(context, sub); DurableTopicSubscription dsub = (DurableTopicSubscription) sub; super.addSubscription(context, sub); sub.add(context, this); if(dsub.isActive()) { synchronized (consumers) { } else { for (Subscription currentSub : consumers) { if (currentSub.getConsumerInfo().isDurable()) { DurableTopicSubscription dcurrentSub = (DurableTopicSubscription) currentSub; if (dcurrentSub.getSubscriptionKey().equals(dsub.getSubscriptionKey())) {
/** * The subscription should release as may references as it can to help the * garbage collector reclaim memory. */ public void gc() { if (subscription != null) { subscription.gc(); } }
/** * Return true if this subscription matches the given destination * * @param destination the destination to compare against * @return true if this subscription matches the given destination */ public boolean matchesDestination(ActiveMQDestination destination) { ActiveMQDestination subscriptionDestination = subscription.getActiveMQDestination(); DestinationFilter filter = DestinationFilter.parseFilter(subscriptionDestination); return filter.matches(destination); }
LOG.trace("Connection {} being aborted because of slow consumer: {} on destination: {}", new Object[] { connection.getConnectionId(), subscription.getConsumerInfo().getConsumerId(), subscription.getActiveMQDestination() }); final Subscription subToClose = subscription; LOG.info("aborting slow consumer: {} for destination:{}", subscription.getConsumerInfo().getConsumerId(), subscription.getActiveMQDestination()); stopConsumer.setConsumerId(subscription.getConsumerInfo().getConsumerId()); stopConsumer.setClose(true); connection.dispatchAsync(stopConsumer); } catch (Exception e) { LOG.info("exception on aborting slow consumer: {}", subscription.getConsumerInfo().getConsumerId(), e); LOG.info("exception on local remove of slow consumer: {}", subscription.getConsumerInfo().getConsumerId(), e);
/** * @return number of messages queued by the client */ @Override public long getDequeueCounter() { return subscription != null ? subscription.getDequeueCounter() : 0; }
protected void destroySubscription(Subscription sub) { sub.destroy(); }
@Override public void acknowledge(ConsumerBrokerExchange consumerExchange, MessageAck ack) throws Exception { Subscription sub = consumerExchange.getSubscription(); if (sub == null) { sub = subscriptions.get(ack.getConsumerId()); if (sub == null) { if (!consumerExchange.getConnectionContext().isInRecoveryMode()) { LOG.warn("Ack for non existent subscription, ack: {}", ack); throw new IllegalArgumentException("The subscription does not exist: " + ack.getConsumerId()); } else { LOG.debug("Ack for non existent subscription in recovery, ack: {}", ack); return; } } consumerExchange.setSubscription(sub); } sub.acknowledge(consumerExchange.getConnectionContext(), ack); }
private int getConsumerMessageCountBeforeFull() throws Exception { int total = 0; boolean zeroPrefetch = false; consumersLock.readLock().lock(); try{ for (Subscription s : consumers) { zeroPrefetch |= s.getPrefetchSize() == 0; int countBeforeFull = s.countBeforeFull(); total += countBeforeFull; } }finally { consumersLock.readLock().unlock(); } if (total == 0 && zeroPrefetch) { total = 1; } return total; }
/** * @returns the ObjectName of the Connection that created this subscription */ @Override public ObjectName getConnection() { ObjectName result = null; if (clientId != null && subscription != null) { ConnectionContext ctx = subscription.getContext(); if (ctx != null && ctx.getBroker() != null && ctx.getBroker().getBrokerService() != null) { BrokerService service = ctx.getBroker().getBrokerService(); ManagementContext managementCtx = service.getManagementContext(); if (managementCtx != null) { try { ObjectName query = createConnectionQuery(managementCtx, service.getBrokerName()); Set<ObjectName> names = managementCtx.queryNames(query, null); if (names.size() == 1) { result = names.iterator().next(); } } catch (Exception e) { } } } } return result; }