john weidman created AMQNET-570:
-----------------------------------

             Summary: Error in Apache.NMS.ActiveMQ.Connection.Close()
                 Key: AMQNET-570
                 URL: https://issues.apache.org/jira/browse/AMQNET-570
             Project: ActiveMQ .Net
          Issue Type: Bug
          Components: ActiveMQ
    Affects Versions: 1.7.2
         Environment: Windows Server 2008 R2
            Reporter: john weidman


We have been having issues with our ActiveMQ server and we think we have 
tracked at least part of the issue to a bug in the Close function of the 
Apache.NMS.ActiveMQ.Connection class. In the close function it appear to try to 
cleanup temporary destinations here:

{code}
if(this.tempDests.Count > 0)
{
        // Make a copy of the destinations to delete, because the act of 
deleting
        // them will modify the collection.
        ActiveMQTempDestination[] tempDestsToDelete = new 
ActiveMQTempDestination[this.tempDests.Count];

        this.tempDests.Values.CopyTo(tempDestsToDelete, 0);
        foreach(ActiveMQTempDestination dest in tempDestsToDelete)
        {
                dest.Delete();
        }
}
{code}

We have seen the following exceptions:
- "System.NullReferenceException" on {{dest.Delete()}}
- "System.IndexOutOfRangeException: Index was outside the bounds of the array." 
on {{this.tempDests.Values.CopyTo(tempDestsToDelete, 0)}}
- "System.ArgumentException: Destination array is not long enough to copy all 
the items in the collection. Check array index and length." on 
{{this.tempDests.Values.CopyTo(tempDestsToDelete, 0)}}

I assume that this is because of the length of {{tempDests}} is changing during 
the close. It seems like a {{lock(this.tempDests.SyncRoot)}} would be necessary 
around this section, something like:

{code}
if(this.tempDests.Count > 0)
{
        lock (this.tempDests.SyncRoot)
        {
                // Make a copy of the destinations to delete, because the act 
of deleting
                // them will modify the collection.
                ActiveMQTempDestination[] tempDestsToDelete = new 
ActiveMQTempDestination[this.tempDests.Count];

                this.tempDests.Values.CopyTo(tempDestsToDelete, 0);
                foreach (ActiveMQTempDestination dest in tempDestsToDelete)
                {
                        dest.Delete();
                }
        }
}
{code}

Because of the exceptions about 1 out of 1,000 connections in our system do not 
get closed, and causes issues with the performance of ActiveMQ, to the point of 
needing restarting every few days.



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to