You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@activemq.apache.org by "Timothy Bish (JIRA)" <ji...@apache.org> on 2008/12/31 23:43:05 UTC

[jira] Created: (AMQ-2051) Removing a Destination with active subscribers causes the destination to be unable to be removed.

Removing a Destination with active subscribers causes the destination to be unable to be removed.
-------------------------------------------------------------------------------------------------

                 Key: AMQ-2051
                 URL: https://issues.apache.org/activemq/browse/AMQ-2051
             Project: ActiveMQ
          Issue Type: Bug
          Components: Broker
    Affects Versions: 5.2.0, 5.1.0
            Reporter: Timothy Bish
            Priority: Minor
             Fix For: 5.3.0
         Attachments: RemoveDestinationTest.java

While attempting to implement destination removal in the ActiveMQ-CPP client I noticed that when attempting to remove destination that had active subscribers the destination would be placed in a state that they could not be removed once the subscribers had all been removed.  

Sending a DestinationInfo command to the Broker while keeping my consumer open results in an exception which is expected since there are still subscribers.  

{noformat}
javax.jms.JMSException: Destination still has an active subscription: topic://TEST.FOO
	at org.apache.activemq.broker.region.AbstractRegion.removeDestination(AbstractRegion.java:158)
	at org.apache.activemq.broker.jmx.ManagedTopicRegion.removeDestination(ManagedTopicRegion.java:62)
	at org.apache.activemq.broker.region.RegionBroker.removeDestination(RegionBroker.java:289)
	at org.apache.activemq.broker.region.RegionBroker.removeDestinationInfo(RegionBroker.java:312)
	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
	at org.apache.activemq.advisory.AdvisoryBroker.removeDestinationInfo(AdvisoryBroker.java:193)
	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
	at org.apache.activemq.broker.MutableBrokerFilter.removeDestinationInfo(MutableBrokerFilter.java:226)
	at org.apache.activemq.broker.TransportConnection.processRemoveDestination(TransportConnection.java:481)
	at org.apache.activemq.command.DestinationInfo.visit(DestinationInfo.java:124)
	at org.apache.activemq.broker.TransportConnection.service(TransportConnection.java:305)
	at org.apache.activemq.broker.TransportConnection$1.onCommand(TransportConnection.java:179)
	at org.apache.activemq.transport.ResponseCorrelator.onCommand(ResponseCorrelator.java:104)
	at org.apache.activemq.transport.TransportFilter.onCommand(TransportFilter.java:68)
	at org.apache.activemq.transport.vm.VMTransport.iterate(VMTransport.java:205)
	at org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.java:122)
	at org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.java:43)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
	at java.lang.Thread.run(Thread.java:619)
{noformat}

Once I removed my consumer and sent the command again I got no errors indicating that it couldn't be removed, however I could still see the Destination in the Web Console.

Looking into the Broker code I see that the RegionBroker class processes a removeDestination call by first removing the Destination from its map of Destinations and then attempting to remove it from the Region that it belongs to.  If this call fails the code will never again attempt to remove a Destination since its removed from the RegionBroker's map but it may not be removed from the specific region it resides in.  The code looks like it should first attempt to remove the Destination from the region before removing from its map, the addDestination method works in that way, adding it to region before adding it to its map so that if an exception occurs nothing is added.

RegionBroker.java : around line 283

{noformat|
    public void removeDestination(ConnectionContext context, ActiveMQDestination destination, long timeout) throws Exception {

        if (destinations.remove(destination) != null) {
            switch (destination.getDestinationType()) {
            case ActiveMQDestination.QUEUE_TYPE:
                queueRegion.removeDestination(context, destination, timeout);
                break;
            case ActiveMQDestination.TOPIC_TYPE:
                topicRegion.removeDestination(context, destination, timeout);
                break;
            case ActiveMQDestination.TEMP_QUEUE_TYPE:
                tempQueueRegion.removeDestination(context, destination, timeout);
                break;
            case ActiveMQDestination.TEMP_TOPIC_TYPE:
                tempTopicRegion.removeDestination(context, destination, timeout);
                break;
            default:
                throw createUnknownDestinationTypeException(destination);
            }
        }

    }
{noformat}


-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Assigned: (AMQ-2051) Removing a Destination with active subscribers causes the destination to be unable to be removed.

Posted by "Timothy Bish (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/activemq/browse/AMQ-2051?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Timothy Bish reassigned AMQ-2051:
---------------------------------

    Assignee: Gary Tully

Gary, can you take a look at this one for me, we talked about this issue in December, would like to get your input on what I've found.

> Removing a Destination with active subscribers causes the destination to be unable to be removed.
> -------------------------------------------------------------------------------------------------
>
>                 Key: AMQ-2051
>                 URL: https://issues.apache.org/activemq/browse/AMQ-2051
>             Project: ActiveMQ
>          Issue Type: Bug
>          Components: Broker
>    Affects Versions: 5.1.0, 5.2.0
>            Reporter: Timothy Bish
>            Assignee: Gary Tully
>            Priority: Minor
>             Fix For: 5.3.0
>
>         Attachments: removeDestinationPatch.txt, RemoveDestinationTest.java
>
>
> While attempting to implement destination removal in the ActiveMQ-CPP client I noticed that when attempting to remove destination that had active subscribers the destination would be placed in a state that they could not be removed once the subscribers had all been removed.  
> Sending a DestinationInfo command to the Broker while keeping my consumer open results in an exception which is expected since there are still subscribers.  
> {noformat}
> javax.jms.JMSException: Destination still has an active subscription: topic://TEST.FOO
> 	at org.apache.activemq.broker.region.AbstractRegion.removeDestination(AbstractRegion.java:158)
> 	at org.apache.activemq.broker.jmx.ManagedTopicRegion.removeDestination(ManagedTopicRegion.java:62)
> 	at org.apache.activemq.broker.region.RegionBroker.removeDestination(RegionBroker.java:289)
> 	at org.apache.activemq.broker.region.RegionBroker.removeDestinationInfo(RegionBroker.java:312)
> 	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
> 	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
> 	at org.apache.activemq.advisory.AdvisoryBroker.removeDestinationInfo(AdvisoryBroker.java:193)
> 	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
> 	at org.apache.activemq.broker.MutableBrokerFilter.removeDestinationInfo(MutableBrokerFilter.java:226)
> 	at org.apache.activemq.broker.TransportConnection.processRemoveDestination(TransportConnection.java:481)
> 	at org.apache.activemq.command.DestinationInfo.visit(DestinationInfo.java:124)
> 	at org.apache.activemq.broker.TransportConnection.service(TransportConnection.java:305)
> 	at org.apache.activemq.broker.TransportConnection$1.onCommand(TransportConnection.java:179)
> 	at org.apache.activemq.transport.ResponseCorrelator.onCommand(ResponseCorrelator.java:104)
> 	at org.apache.activemq.transport.TransportFilter.onCommand(TransportFilter.java:68)
> 	at org.apache.activemq.transport.vm.VMTransport.iterate(VMTransport.java:205)
> 	at org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.java:122)
> 	at org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.java:43)
> 	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
> 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
> 	at java.lang.Thread.run(Thread.java:619)
> {noformat}
> Once I removed my consumer and sent the command again I got no errors indicating that it couldn't be removed, however I could still see the Destination in the Web Console.
> Looking into the Broker code I see that the RegionBroker class processes a removeDestination call by first removing the Destination from its map of Destinations and then attempting to remove it from the Region that it belongs to.  If this call fails the code will never again attempt to remove a Destination since its removed from the RegionBroker's map but it may not be removed from the specific region it resides in.  The code looks like it should first attempt to remove the Destination from the region before removing from its map, the addDestination method works in that way, adding it to region before adding it to its map so that if an exception occurs nothing is added.
> RegionBroker.java : around line 283
> {noformat|
>     public void removeDestination(ConnectionContext context, ActiveMQDestination destination, long timeout) throws Exception {
>         if (destinations.remove(destination) != null) {
>             switch (destination.getDestinationType()) {
>             case ActiveMQDestination.QUEUE_TYPE:
>                 queueRegion.removeDestination(context, destination, timeout);
>                 break;
>             case ActiveMQDestination.TOPIC_TYPE:
>                 topicRegion.removeDestination(context, destination, timeout);
>                 break;
>             case ActiveMQDestination.TEMP_QUEUE_TYPE:
>                 tempQueueRegion.removeDestination(context, destination, timeout);
>                 break;
>             case ActiveMQDestination.TEMP_TOPIC_TYPE:
>                 tempTopicRegion.removeDestination(context, destination, timeout);
>                 break;
>             default:
>                 throw createUnknownDestinationTypeException(destination);
>             }
>         }
>     }
> {noformat}

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Resolved: (AMQ-2051) Removing a Destination with active subscribers causes the destination to be unable to be removed.

Posted by "Gary Tully (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/activemq/browse/AMQ-2051?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Gary Tully resolved AMQ-2051.
-----------------------------

    Resolution: Fixed

patch applied and modified test included, thanks. r734524

The remove implementation takes a timeout option, if the timeout is 0, it errors if there are consumers.
if the timeout > 0 it removes the subscribers and disposes the queue, which should purge the queue.

So to Davids question, I guess a removeDestination where the destination has messages should delete the messages, that is purge the store.

> Removing a Destination with active subscribers causes the destination to be unable to be removed.
> -------------------------------------------------------------------------------------------------
>
>                 Key: AMQ-2051
>                 URL: https://issues.apache.org/activemq/browse/AMQ-2051
>             Project: ActiveMQ
>          Issue Type: Bug
>          Components: Broker
>    Affects Versions: 5.1.0, 5.2.0
>            Reporter: Timothy Bish
>            Assignee: Gary Tully
>            Priority: Minor
>             Fix For: 5.3.0
>
>         Attachments: removeDestinationPatch.txt, RemoveDestinationTest.java
>
>
> While attempting to implement destination removal in the ActiveMQ-CPP client I noticed that when attempting to remove destination that had active subscribers the destination would be placed in a state that they could not be removed once the subscribers had all been removed.  
> Sending a DestinationInfo command to the Broker while keeping my consumer open results in an exception which is expected since there are still subscribers.  
> {noformat}
> javax.jms.JMSException: Destination still has an active subscription: topic://TEST.FOO
> 	at org.apache.activemq.broker.region.AbstractRegion.removeDestination(AbstractRegion.java:158)
> 	at org.apache.activemq.broker.jmx.ManagedTopicRegion.removeDestination(ManagedTopicRegion.java:62)
> 	at org.apache.activemq.broker.region.RegionBroker.removeDestination(RegionBroker.java:289)
> 	at org.apache.activemq.broker.region.RegionBroker.removeDestinationInfo(RegionBroker.java:312)
> 	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
> 	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
> 	at org.apache.activemq.advisory.AdvisoryBroker.removeDestinationInfo(AdvisoryBroker.java:193)
> 	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
> 	at org.apache.activemq.broker.MutableBrokerFilter.removeDestinationInfo(MutableBrokerFilter.java:226)
> 	at org.apache.activemq.broker.TransportConnection.processRemoveDestination(TransportConnection.java:481)
> 	at org.apache.activemq.command.DestinationInfo.visit(DestinationInfo.java:124)
> 	at org.apache.activemq.broker.TransportConnection.service(TransportConnection.java:305)
> 	at org.apache.activemq.broker.TransportConnection$1.onCommand(TransportConnection.java:179)
> 	at org.apache.activemq.transport.ResponseCorrelator.onCommand(ResponseCorrelator.java:104)
> 	at org.apache.activemq.transport.TransportFilter.onCommand(TransportFilter.java:68)
> 	at org.apache.activemq.transport.vm.VMTransport.iterate(VMTransport.java:205)
> 	at org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.java:122)
> 	at org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.java:43)
> 	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
> 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
> 	at java.lang.Thread.run(Thread.java:619)
> {noformat}
> Once I removed my consumer and sent the command again I got no errors indicating that it couldn't be removed, however I could still see the Destination in the Web Console.
> Looking into the Broker code I see that the RegionBroker class processes a removeDestination call by first removing the Destination from its map of Destinations and then attempting to remove it from the Region that it belongs to.  If this call fails the code will never again attempt to remove a Destination since its removed from the RegionBroker's map but it may not be removed from the specific region it resides in.  The code looks like it should first attempt to remove the Destination from the region before removing from its map, the addDestination method works in that way, adding it to region before adding it to its map so that if an exception occurs nothing is added.
> RegionBroker.java : around line 283
> {noformat|
>     public void removeDestination(ConnectionContext context, ActiveMQDestination destination, long timeout) throws Exception {
>         if (destinations.remove(destination) != null) {
>             switch (destination.getDestinationType()) {
>             case ActiveMQDestination.QUEUE_TYPE:
>                 queueRegion.removeDestination(context, destination, timeout);
>                 break;
>             case ActiveMQDestination.TOPIC_TYPE:
>                 topicRegion.removeDestination(context, destination, timeout);
>                 break;
>             case ActiveMQDestination.TEMP_QUEUE_TYPE:
>                 tempQueueRegion.removeDestination(context, destination, timeout);
>                 break;
>             case ActiveMQDestination.TEMP_TOPIC_TYPE:
>                 tempTopicRegion.removeDestination(context, destination, timeout);
>                 break;
>             default:
>                 throw createUnknownDestinationTypeException(destination);
>             }
>         }
>     }
> {noformat}

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Updated: (AMQ-2051) Removing a Destination with active subscribers causes the destination to be unable to be removed.

Posted by "Timothy Bish (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/activemq/browse/AMQ-2051?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Timothy Bish updated AMQ-2051:
------------------------------

    Attachment: RemoveDestinationTest.java

I've attached a unit test, I've not been able to find an easy way though to actually test that the Destination is completely removed.



> Removing a Destination with active subscribers causes the destination to be unable to be removed.
> -------------------------------------------------------------------------------------------------
>
>                 Key: AMQ-2051
>                 URL: https://issues.apache.org/activemq/browse/AMQ-2051
>             Project: ActiveMQ
>          Issue Type: Bug
>          Components: Broker
>    Affects Versions: 5.1.0, 5.2.0
>            Reporter: Timothy Bish
>            Priority: Minor
>             Fix For: 5.3.0
>
>         Attachments: RemoveDestinationTest.java
>
>
> While attempting to implement destination removal in the ActiveMQ-CPP client I noticed that when attempting to remove destination that had active subscribers the destination would be placed in a state that they could not be removed once the subscribers had all been removed.  
> Sending a DestinationInfo command to the Broker while keeping my consumer open results in an exception which is expected since there are still subscribers.  
> {noformat}
> javax.jms.JMSException: Destination still has an active subscription: topic://TEST.FOO
> 	at org.apache.activemq.broker.region.AbstractRegion.removeDestination(AbstractRegion.java:158)
> 	at org.apache.activemq.broker.jmx.ManagedTopicRegion.removeDestination(ManagedTopicRegion.java:62)
> 	at org.apache.activemq.broker.region.RegionBroker.removeDestination(RegionBroker.java:289)
> 	at org.apache.activemq.broker.region.RegionBroker.removeDestinationInfo(RegionBroker.java:312)
> 	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
> 	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
> 	at org.apache.activemq.advisory.AdvisoryBroker.removeDestinationInfo(AdvisoryBroker.java:193)
> 	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
> 	at org.apache.activemq.broker.MutableBrokerFilter.removeDestinationInfo(MutableBrokerFilter.java:226)
> 	at org.apache.activemq.broker.TransportConnection.processRemoveDestination(TransportConnection.java:481)
> 	at org.apache.activemq.command.DestinationInfo.visit(DestinationInfo.java:124)
> 	at org.apache.activemq.broker.TransportConnection.service(TransportConnection.java:305)
> 	at org.apache.activemq.broker.TransportConnection$1.onCommand(TransportConnection.java:179)
> 	at org.apache.activemq.transport.ResponseCorrelator.onCommand(ResponseCorrelator.java:104)
> 	at org.apache.activemq.transport.TransportFilter.onCommand(TransportFilter.java:68)
> 	at org.apache.activemq.transport.vm.VMTransport.iterate(VMTransport.java:205)
> 	at org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.java:122)
> 	at org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.java:43)
> 	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
> 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
> 	at java.lang.Thread.run(Thread.java:619)
> {noformat}
> Once I removed my consumer and sent the command again I got no errors indicating that it couldn't be removed, however I could still see the Destination in the Web Console.
> Looking into the Broker code I see that the RegionBroker class processes a removeDestination call by first removing the Destination from its map of Destinations and then attempting to remove it from the Region that it belongs to.  If this call fails the code will never again attempt to remove a Destination since its removed from the RegionBroker's map but it may not be removed from the specific region it resides in.  The code looks like it should first attempt to remove the Destination from the region before removing from its map, the addDestination method works in that way, adding it to region before adding it to its map so that if an exception occurs nothing is added.
> RegionBroker.java : around line 283
> {noformat|
>     public void removeDestination(ConnectionContext context, ActiveMQDestination destination, long timeout) throws Exception {
>         if (destinations.remove(destination) != null) {
>             switch (destination.getDestinationType()) {
>             case ActiveMQDestination.QUEUE_TYPE:
>                 queueRegion.removeDestination(context, destination, timeout);
>                 break;
>             case ActiveMQDestination.TOPIC_TYPE:
>                 topicRegion.removeDestination(context, destination, timeout);
>                 break;
>             case ActiveMQDestination.TEMP_QUEUE_TYPE:
>                 tempQueueRegion.removeDestination(context, destination, timeout);
>                 break;
>             case ActiveMQDestination.TEMP_TOPIC_TYPE:
>                 tempTopicRegion.removeDestination(context, destination, timeout);
>                 break;
>             default:
>                 throw createUnknownDestinationTypeException(destination);
>             }
>         }
>     }
> {noformat}

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Updated: (AMQ-2051) Removing a Destination with active subscribers causes the destination to be unable to be removed.

Posted by "Gary Tully (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/activemq/browse/AMQ-2051?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Gary Tully updated AMQ-2051:
----------------------------

    Description: 
While attempting to implement destination removal in the ActiveMQ-CPP client I noticed that when attempting to remove destination that had active subscribers the destination would be placed in a state that they could not be removed once the subscribers had all been removed.  

Sending a DestinationInfo command to the Broker while keeping my consumer open results in an exception which is expected since there are still subscribers.  

{code}
javax.jms.JMSException: Destination still has an active subscription: topic://TEST.FOO
	at org.apache.activemq.broker.region.AbstractRegion.removeDestination(AbstractRegion.java:158)
	at org.apache.activemq.broker.jmx.ManagedTopicRegion.removeDestination(ManagedTopicRegion.java:62)
	at org.apache.activemq.broker.region.RegionBroker.removeDestination(RegionBroker.java:289)
	at org.apache.activemq.broker.region.RegionBroker.removeDestinationInfo(RegionBroker.java:312)
	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
	at org.apache.activemq.advisory.AdvisoryBroker.removeDestinationInfo(AdvisoryBroker.java:193)
	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
	at org.apache.activemq.broker.MutableBrokerFilter.removeDestinationInfo(MutableBrokerFilter.java:226)
	at org.apache.activemq.broker.TransportConnection.processRemoveDestination(TransportConnection.java:481)
	at org.apache.activemq.command.DestinationInfo.visit(DestinationInfo.java:124)
	at org.apache.activemq.broker.TransportConnection.service(TransportConnection.java:305)
	at org.apache.activemq.broker.TransportConnection$1.onCommand(TransportConnection.java:179)
	at org.apache.activemq.transport.ResponseCorrelator.onCommand(ResponseCorrelator.java:104)
	at org.apache.activemq.transport.TransportFilter.onCommand(TransportFilter.java:68)
	at org.apache.activemq.transport.vm.VMTransport.iterate(VMTransport.java:205)
	at org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.java:122)
	at org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.java:43)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
	at java.lang.Thread.run(Thread.java:619)
{code}

Once I removed my consumer and sent the command again I got no errors indicating that it couldn't be removed, however I could still see the Destination in the Web Console.

Looking into the Broker code I see that the RegionBroker class processes a removeDestination call by first removing the Destination from its map of Destinations and then attempting to remove it from the Region that it belongs to.  If this call fails the code will never again attempt to remove a Destination since its removed from the RegionBroker's map but it may not be removed from the specific region it resides in.  The code looks like it should first attempt to remove the Destination from the region before removing from its map, the addDestination method works in that way, adding it to region before adding it to its map so that if an exception occurs nothing is added.

RegionBroker.java : around line 283

{code}|
    public void removeDestination(ConnectionContext context, ActiveMQDestination destination, long timeout) throws Exception {

        if (destinations.remove(destination) != null) {
            switch (destination.getDestinationType()) {
            case ActiveMQDestination.QUEUE_TYPE:
                queueRegion.removeDestination(context, destination, timeout);
                break;
            case ActiveMQDestination.TOPIC_TYPE:
                topicRegion.removeDestination(context, destination, timeout);
                break;
            case ActiveMQDestination.TEMP_QUEUE_TYPE:
                tempQueueRegion.removeDestination(context, destination, timeout);
                break;
            case ActiveMQDestination.TEMP_TOPIC_TYPE:
                tempTopicRegion.removeDestination(context, destination, timeout);
                break;
            default:
                throw createUnknownDestinationTypeException(destination);
            }
        }

    }
{code}


  was:
While attempting to implement destination removal in the ActiveMQ-CPP client I noticed that when attempting to remove destination that had active subscribers the destination would be placed in a state that they could not be removed once the subscribers had all been removed.  

Sending a DestinationInfo command to the Broker while keeping my consumer open results in an exception which is expected since there are still subscribers.  

{noformat}
javax.jms.JMSException: Destination still has an active subscription: topic://TEST.FOO
	at org.apache.activemq.broker.region.AbstractRegion.removeDestination(AbstractRegion.java:158)
	at org.apache.activemq.broker.jmx.ManagedTopicRegion.removeDestination(ManagedTopicRegion.java:62)
	at org.apache.activemq.broker.region.RegionBroker.removeDestination(RegionBroker.java:289)
	at org.apache.activemq.broker.region.RegionBroker.removeDestinationInfo(RegionBroker.java:312)
	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
	at org.apache.activemq.advisory.AdvisoryBroker.removeDestinationInfo(AdvisoryBroker.java:193)
	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
	at org.apache.activemq.broker.MutableBrokerFilter.removeDestinationInfo(MutableBrokerFilter.java:226)
	at org.apache.activemq.broker.TransportConnection.processRemoveDestination(TransportConnection.java:481)
	at org.apache.activemq.command.DestinationInfo.visit(DestinationInfo.java:124)
	at org.apache.activemq.broker.TransportConnection.service(TransportConnection.java:305)
	at org.apache.activemq.broker.TransportConnection$1.onCommand(TransportConnection.java:179)
	at org.apache.activemq.transport.ResponseCorrelator.onCommand(ResponseCorrelator.java:104)
	at org.apache.activemq.transport.TransportFilter.onCommand(TransportFilter.java:68)
	at org.apache.activemq.transport.vm.VMTransport.iterate(VMTransport.java:205)
	at org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.java:122)
	at org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.java:43)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
	at java.lang.Thread.run(Thread.java:619)
{noformat}

Once I removed my consumer and sent the command again I got no errors indicating that it couldn't be removed, however I could still see the Destination in the Web Console.

Looking into the Broker code I see that the RegionBroker class processes a removeDestination call by first removing the Destination from its map of Destinations and then attempting to remove it from the Region that it belongs to.  If this call fails the code will never again attempt to remove a Destination since its removed from the RegionBroker's map but it may not be removed from the specific region it resides in.  The code looks like it should first attempt to remove the Destination from the region before removing from its map, the addDestination method works in that way, adding it to region before adding it to its map so that if an exception occurs nothing is added.

RegionBroker.java : around line 283

{noformat|
    public void removeDestination(ConnectionContext context, ActiveMQDestination destination, long timeout) throws Exception {

        if (destinations.remove(destination) != null) {
            switch (destination.getDestinationType()) {
            case ActiveMQDestination.QUEUE_TYPE:
                queueRegion.removeDestination(context, destination, timeout);
                break;
            case ActiveMQDestination.TOPIC_TYPE:
                topicRegion.removeDestination(context, destination, timeout);
                break;
            case ActiveMQDestination.TEMP_QUEUE_TYPE:
                tempQueueRegion.removeDestination(context, destination, timeout);
                break;
            case ActiveMQDestination.TEMP_TOPIC_TYPE:
                tempTopicRegion.removeDestination(context, destination, timeout);
                break;
            default:
                throw createUnknownDestinationTypeException(destination);
            }
        }

    }
{noformat}



> Removing a Destination with active subscribers causes the destination to be unable to be removed.
> -------------------------------------------------------------------------------------------------
>
>                 Key: AMQ-2051
>                 URL: https://issues.apache.org/activemq/browse/AMQ-2051
>             Project: ActiveMQ
>          Issue Type: Bug
>          Components: Broker
>    Affects Versions: 5.1.0, 5.2.0
>            Reporter: Timothy Bish
>            Assignee: Gary Tully
>            Priority: Minor
>             Fix For: 5.3.0
>
>         Attachments: removeDestinationPatch.txt, RemoveDestinationTest.java
>
>
> While attempting to implement destination removal in the ActiveMQ-CPP client I noticed that when attempting to remove destination that had active subscribers the destination would be placed in a state that they could not be removed once the subscribers had all been removed.  
> Sending a DestinationInfo command to the Broker while keeping my consumer open results in an exception which is expected since there are still subscribers.  
> {code}
> javax.jms.JMSException: Destination still has an active subscription: topic://TEST.FOO
> 	at org.apache.activemq.broker.region.AbstractRegion.removeDestination(AbstractRegion.java:158)
> 	at org.apache.activemq.broker.jmx.ManagedTopicRegion.removeDestination(ManagedTopicRegion.java:62)
> 	at org.apache.activemq.broker.region.RegionBroker.removeDestination(RegionBroker.java:289)
> 	at org.apache.activemq.broker.region.RegionBroker.removeDestinationInfo(RegionBroker.java:312)
> 	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
> 	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
> 	at org.apache.activemq.advisory.AdvisoryBroker.removeDestinationInfo(AdvisoryBroker.java:193)
> 	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
> 	at org.apache.activemq.broker.MutableBrokerFilter.removeDestinationInfo(MutableBrokerFilter.java:226)
> 	at org.apache.activemq.broker.TransportConnection.processRemoveDestination(TransportConnection.java:481)
> 	at org.apache.activemq.command.DestinationInfo.visit(DestinationInfo.java:124)
> 	at org.apache.activemq.broker.TransportConnection.service(TransportConnection.java:305)
> 	at org.apache.activemq.broker.TransportConnection$1.onCommand(TransportConnection.java:179)
> 	at org.apache.activemq.transport.ResponseCorrelator.onCommand(ResponseCorrelator.java:104)
> 	at org.apache.activemq.transport.TransportFilter.onCommand(TransportFilter.java:68)
> 	at org.apache.activemq.transport.vm.VMTransport.iterate(VMTransport.java:205)
> 	at org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.java:122)
> 	at org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.java:43)
> 	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
> 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
> 	at java.lang.Thread.run(Thread.java:619)
> {code}
> Once I removed my consumer and sent the command again I got no errors indicating that it couldn't be removed, however I could still see the Destination in the Web Console.
> Looking into the Broker code I see that the RegionBroker class processes a removeDestination call by first removing the Destination from its map of Destinations and then attempting to remove it from the Region that it belongs to.  If this call fails the code will never again attempt to remove a Destination since its removed from the RegionBroker's map but it may not be removed from the specific region it resides in.  The code looks like it should first attempt to remove the Destination from the region before removing from its map, the addDestination method works in that way, adding it to region before adding it to its map so that if an exception occurs nothing is added.
> RegionBroker.java : around line 283
> {code}|
>     public void removeDestination(ConnectionContext context, ActiveMQDestination destination, long timeout) throws Exception {
>         if (destinations.remove(destination) != null) {
>             switch (destination.getDestinationType()) {
>             case ActiveMQDestination.QUEUE_TYPE:
>                 queueRegion.removeDestination(context, destination, timeout);
>                 break;
>             case ActiveMQDestination.TOPIC_TYPE:
>                 topicRegion.removeDestination(context, destination, timeout);
>                 break;
>             case ActiveMQDestination.TEMP_QUEUE_TYPE:
>                 tempQueueRegion.removeDestination(context, destination, timeout);
>                 break;
>             case ActiveMQDestination.TEMP_TOPIC_TYPE:
>                 tempTopicRegion.removeDestination(context, destination, timeout);
>                 break;
>             default:
>                 throw createUnknownDestinationTypeException(destination);
>             }
>         }
>     }
> {code}

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Commented: (AMQ-2051) Removing a Destination with active subscribers causes the destination to be unable to be removed.

Posted by "David Jencks (JIRA)" <ji...@apache.org>.
    [ https://issues.apache.org/activemq/browse/AMQ-2051?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=48668#action_48668 ] 

David Jencks commented on AMQ-2051:
-----------------------------------

This doesn't seem to be a complete fix.  AFAICT the subscriptions still have the references to any messages that were in the queue when it was destroyed.  Trying to recreate the queue results in recovery failures as these references don't find the messages they refer to.

I have to say I'm confused about what should happen when you destroyDestination for a destination that has active consumers and messages in it.  In the case I am working with the consumer was discarded without being closed so it doesn't much matter what state the client end of the consumer is in but I wonder what should happen if the consumer is actually being used.

> Removing a Destination with active subscribers causes the destination to be unable to be removed.
> -------------------------------------------------------------------------------------------------
>
>                 Key: AMQ-2051
>                 URL: https://issues.apache.org/activemq/browse/AMQ-2051
>             Project: ActiveMQ
>          Issue Type: Bug
>          Components: Broker
>    Affects Versions: 5.1.0, 5.2.0
>            Reporter: Timothy Bish
>            Assignee: Gary Tully
>            Priority: Minor
>             Fix For: 5.3.0
>
>         Attachments: removeDestinationPatch.txt, RemoveDestinationTest.java
>
>
> While attempting to implement destination removal in the ActiveMQ-CPP client I noticed that when attempting to remove destination that had active subscribers the destination would be placed in a state that they could not be removed once the subscribers had all been removed.  
> Sending a DestinationInfo command to the Broker while keeping my consumer open results in an exception which is expected since there are still subscribers.  
> {noformat}
> javax.jms.JMSException: Destination still has an active subscription: topic://TEST.FOO
> 	at org.apache.activemq.broker.region.AbstractRegion.removeDestination(AbstractRegion.java:158)
> 	at org.apache.activemq.broker.jmx.ManagedTopicRegion.removeDestination(ManagedTopicRegion.java:62)
> 	at org.apache.activemq.broker.region.RegionBroker.removeDestination(RegionBroker.java:289)
> 	at org.apache.activemq.broker.region.RegionBroker.removeDestinationInfo(RegionBroker.java:312)
> 	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
> 	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
> 	at org.apache.activemq.advisory.AdvisoryBroker.removeDestinationInfo(AdvisoryBroker.java:193)
> 	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
> 	at org.apache.activemq.broker.MutableBrokerFilter.removeDestinationInfo(MutableBrokerFilter.java:226)
> 	at org.apache.activemq.broker.TransportConnection.processRemoveDestination(TransportConnection.java:481)
> 	at org.apache.activemq.command.DestinationInfo.visit(DestinationInfo.java:124)
> 	at org.apache.activemq.broker.TransportConnection.service(TransportConnection.java:305)
> 	at org.apache.activemq.broker.TransportConnection$1.onCommand(TransportConnection.java:179)
> 	at org.apache.activemq.transport.ResponseCorrelator.onCommand(ResponseCorrelator.java:104)
> 	at org.apache.activemq.transport.TransportFilter.onCommand(TransportFilter.java:68)
> 	at org.apache.activemq.transport.vm.VMTransport.iterate(VMTransport.java:205)
> 	at org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.java:122)
> 	at org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.java:43)
> 	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
> 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
> 	at java.lang.Thread.run(Thread.java:619)
> {noformat}
> Once I removed my consumer and sent the command again I got no errors indicating that it couldn't be removed, however I could still see the Destination in the Web Console.
> Looking into the Broker code I see that the RegionBroker class processes a removeDestination call by first removing the Destination from its map of Destinations and then attempting to remove it from the Region that it belongs to.  If this call fails the code will never again attempt to remove a Destination since its removed from the RegionBroker's map but it may not be removed from the specific region it resides in.  The code looks like it should first attempt to remove the Destination from the region before removing from its map, the addDestination method works in that way, adding it to region before adding it to its map so that if an exception occurs nothing is added.
> RegionBroker.java : around line 283
> {noformat|
>     public void removeDestination(ConnectionContext context, ActiveMQDestination destination, long timeout) throws Exception {
>         if (destinations.remove(destination) != null) {
>             switch (destination.getDestinationType()) {
>             case ActiveMQDestination.QUEUE_TYPE:
>                 queueRegion.removeDestination(context, destination, timeout);
>                 break;
>             case ActiveMQDestination.TOPIC_TYPE:
>                 topicRegion.removeDestination(context, destination, timeout);
>                 break;
>             case ActiveMQDestination.TEMP_QUEUE_TYPE:
>                 tempQueueRegion.removeDestination(context, destination, timeout);
>                 break;
>             case ActiveMQDestination.TEMP_TOPIC_TYPE:
>                 tempTopicRegion.removeDestination(context, destination, timeout);
>                 break;
>             default:
>                 throw createUnknownDestinationTypeException(destination);
>             }
>         }
>     }
> {noformat}

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Updated: (AMQ-2051) Removing a Destination with active subscribers causes the destination to be unable to be removed.

Posted by "Timothy Bish (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/activemq/browse/AMQ-2051?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Timothy Bish updated AMQ-2051:
------------------------------

    Attachment: removeDestinationPatch.txt

Potential Patch for this issue.  Probably need someone with more knowledge of the broker internals to ensure this won't break anything.

> Removing a Destination with active subscribers causes the destination to be unable to be removed.
> -------------------------------------------------------------------------------------------------
>
>                 Key: AMQ-2051
>                 URL: https://issues.apache.org/activemq/browse/AMQ-2051
>             Project: ActiveMQ
>          Issue Type: Bug
>          Components: Broker
>    Affects Versions: 5.1.0, 5.2.0
>            Reporter: Timothy Bish
>            Priority: Minor
>             Fix For: 5.3.0
>
>         Attachments: removeDestinationPatch.txt, RemoveDestinationTest.java
>
>
> While attempting to implement destination removal in the ActiveMQ-CPP client I noticed that when attempting to remove destination that had active subscribers the destination would be placed in a state that they could not be removed once the subscribers had all been removed.  
> Sending a DestinationInfo command to the Broker while keeping my consumer open results in an exception which is expected since there are still subscribers.  
> {noformat}
> javax.jms.JMSException: Destination still has an active subscription: topic://TEST.FOO
> 	at org.apache.activemq.broker.region.AbstractRegion.removeDestination(AbstractRegion.java:158)
> 	at org.apache.activemq.broker.jmx.ManagedTopicRegion.removeDestination(ManagedTopicRegion.java:62)
> 	at org.apache.activemq.broker.region.RegionBroker.removeDestination(RegionBroker.java:289)
> 	at org.apache.activemq.broker.region.RegionBroker.removeDestinationInfo(RegionBroker.java:312)
> 	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
> 	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
> 	at org.apache.activemq.advisory.AdvisoryBroker.removeDestinationInfo(AdvisoryBroker.java:193)
> 	at org.apache.activemq.broker.BrokerFilter.removeDestinationInfo(BrokerFilter.java:218)
> 	at org.apache.activemq.broker.MutableBrokerFilter.removeDestinationInfo(MutableBrokerFilter.java:226)
> 	at org.apache.activemq.broker.TransportConnection.processRemoveDestination(TransportConnection.java:481)
> 	at org.apache.activemq.command.DestinationInfo.visit(DestinationInfo.java:124)
> 	at org.apache.activemq.broker.TransportConnection.service(TransportConnection.java:305)
> 	at org.apache.activemq.broker.TransportConnection$1.onCommand(TransportConnection.java:179)
> 	at org.apache.activemq.transport.ResponseCorrelator.onCommand(ResponseCorrelator.java:104)
> 	at org.apache.activemq.transport.TransportFilter.onCommand(TransportFilter.java:68)
> 	at org.apache.activemq.transport.vm.VMTransport.iterate(VMTransport.java:205)
> 	at org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.java:122)
> 	at org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.java:43)
> 	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
> 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
> 	at java.lang.Thread.run(Thread.java:619)
> {noformat}
> Once I removed my consumer and sent the command again I got no errors indicating that it couldn't be removed, however I could still see the Destination in the Web Console.
> Looking into the Broker code I see that the RegionBroker class processes a removeDestination call by first removing the Destination from its map of Destinations and then attempting to remove it from the Region that it belongs to.  If this call fails the code will never again attempt to remove a Destination since its removed from the RegionBroker's map but it may not be removed from the specific region it resides in.  The code looks like it should first attempt to remove the Destination from the region before removing from its map, the addDestination method works in that way, adding it to region before adding it to its map so that if an exception occurs nothing is added.
> RegionBroker.java : around line 283
> {noformat|
>     public void removeDestination(ConnectionContext context, ActiveMQDestination destination, long timeout) throws Exception {
>         if (destinations.remove(destination) != null) {
>             switch (destination.getDestinationType()) {
>             case ActiveMQDestination.QUEUE_TYPE:
>                 queueRegion.removeDestination(context, destination, timeout);
>                 break;
>             case ActiveMQDestination.TOPIC_TYPE:
>                 topicRegion.removeDestination(context, destination, timeout);
>                 break;
>             case ActiveMQDestination.TEMP_QUEUE_TYPE:
>                 tempQueueRegion.removeDestination(context, destination, timeout);
>                 break;
>             case ActiveMQDestination.TEMP_TOPIC_TYPE:
>                 tempTopicRegion.removeDestination(context, destination, timeout);
>                 break;
>             default:
>                 throw createUnknownDestinationTypeException(destination);
>             }
>         }
>     }
> {noformat}

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.