Return-Path: X-Original-To: apmail-activemq-dev-archive@www.apache.org Delivered-To: apmail-activemq-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id DD175DEDA for ; Wed, 31 Oct 2012 06:23:19 +0000 (UTC) Received: (qmail 73666 invoked by uid 500); 31 Oct 2012 06:23:19 -0000 Delivered-To: apmail-activemq-dev-archive@activemq.apache.org Received: (qmail 73214 invoked by uid 500); 31 Oct 2012 06:23:18 -0000 Mailing-List: contact dev-help@activemq.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@activemq.apache.org Delivered-To: mailing list dev@activemq.apache.org Received: (qmail 72461 invoked by uid 99); 31 Oct 2012 06:23:15 -0000 Received: from arcas.apache.org (HELO arcas.apache.org) (140.211.11.28) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 31 Oct 2012 06:23:15 +0000 Date: Wed, 31 Oct 2012 06:23:14 +0000 (UTC) From: "Stirling Chow (JIRA)" To: dev@activemq.apache.org Message-ID: <1108464271.49341.1351664594902.JavaMail.jiratomcat@arcas> Subject: [jira] [Created] (AMQ-4148) Static subscriptions from network bridges do not respect TTL (off by one in calculation), resulting in duplicate consumers. MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394 Stirling Chow created AMQ-4148: ---------------------------------- Summary: Static subscriptions from network bridges do not respect TTL (off by one in calculation), resulting in duplicate consumers. Key: AMQ-4148 URL: https://issues.apache.org/jira/browse/AMQ-4148 Project: ActiveMQ Issue Type: Bug Affects Versions: 5.8.0 Reporter: Stirling Chow Symptom ======= The remote broker path is not set on network consumers that result from static subscriptions; as a result, they are forwarded to other bridges even when the network TTL on the bridges is 1. In an n+1 hub-and-spoke network, the next broker to join receives n subscriptions instead of 1. Cause ===== A consumer for a static subscriptions is created by the following code: {code:title=DemandForwardingBridgeSupport.java} private void startLocalBridge() throws Throwable { ... if (!disposed.get()) { setupStaticDestinations(); } else { LOG.warn("Network connection between " + localBroker + " and " + remoteBroker + "(" + remoteBrokerName + ") was interrupted during establishment."); } } } /** * Subscriptions for these destinations are always created */ protected void setupStaticDestinations() { ... DemandSubscription sub = createDemandSubscription(dest); try { addSubscription(sub); } catch (IOException e) { LOG.error("Failed to add static destination " + dest, e); } if (LOG.isTraceEnabled()) { LOG.trace("bridging messages for static destination: " + dest); } } } } final protected DemandSubscription createDemandSubscription(ActiveMQDestination destination) { ConsumerInfo info = new ConsumerInfo(); info.setDestination(destination); // the remote info held by the DemandSubscription holds the original consumerId, // the local info get's overwritten info.setConsumerId(new ConsumerId(localSessionInfo.getSessionId(), consumerIdGenerator.getNextSequenceId())); DemandSubscription result = null; try { result = createDemandSubscription(info); } catch (IOException e) { LOG.error("Failed to create DemandSubscription ", e); } return result; } {code} Note how the broker path is *not* set on the {{ConsumerInfo}} that is used for the subscription. In contrast, a consumer for a dynamic subscription does have its broker path updated to indicate that it is from a remote broker: {code:title=DemandForwardingBridgeSupport.java} protected void serviceRemoteCommand(Command command) { if (!disposed.get()) { try { if (command.isMessageDispatch()) { safeWaitUntilStarted(); MessageDispatch md = (MessageDispatch) command; serviceRemoteConsumerAdvisory(md.getMessage().getDataStructure()); ackAdvisory(md.getMessage()); ... private void serviceRemoteConsumerAdvisory(DataStructure data) throws IOException { ... if (addConsumerInfo(info)) { if (LOG.isDebugEnabled()) { LOG.debug(configuration.getBrokerName() + " bridged sub on " + localBroker + " from " + remoteBrokerName + " : " + info); } } else { if (LOG.isDebugEnabled()) { LOG.debug(configuration.getBrokerName() + " Ignoring sub from " + remoteBrokerName + " as already subscribed to matching destination : " + info); } } } ... protected boolean addConsumerInfo(final ConsumerInfo consumerInfo) throws IOException { boolean consumerAdded = false; ConsumerInfo info = consumerInfo.copy(); addRemoteBrokerToBrokerPath(info); ... {code} Because of this difference, a static subscription will be forwarded to new bridges with a {{null}} brokerPath while a dynamic subscription to the same queue will be forwarded with a singleton brokerPath. As a result, static subscriptions will be propagate one further hop than their dynamic counterparts. In the case of a network TTL of 1, the static subscription consumers are unexpected propagated to new bridges, while the dynamic subscription consumers are correctly suppressed. Solution ======== There should be no logical difference between a network consumer created for a static subscription vs. a dynamic subscription. In either case, the bridge creates a consumer on behalf of the remote broker. As such, the consumer for a static subscription should have the remote broker in its broker path because it represents a subscription from that remote broker (even if there is no consumer). -- This message is automatically generated by JIRA. If you think it was sent incorrectly, please contact your JIRA administrators For more information on JIRA, see: http://www.atlassian.com/software/jira