[ 
https://issues.apache.org/jira/browse/MUSE-283?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12556290#action_12556290
 ] 

Vinh Nguyen commented on MUSE-283:
----------------------------------

Hi Chris,
I agree...now I understand your first comment:)  So to fix this bug, the Muse 
code should be changed from:

protected synchronized Collection getSubscriptions()  { 
    return Collections.unmodifiableCollection(_subscriptionsByEPR.values());
}

To:

protected synchronized Collection getSubscriptions()  { 
   return new ArrayList(_subscriptionsByEPR.values()); 
} 

As you pointed out, this ensures that each caller get a new list of the current 
subscriptions, instead of everyone getting the same list and possibly 
encountering the ConcurrentModificationException if the list is modified during 
an iteration.

But I realize now that this still doesn't fully address the race condition 
where a subscription expires at the same time a notification is published.  So 
even if a caller has its own list of subscriptions, then if one of those 
subscriptions expired, the subscription itself doesn't prevent a notification 
from being published afterwards.  This is incorrect behavior.

In SimpleSubscriptionManager, nothing special is done during shutdown(), so a 
subsequent call to its publish() method will still succeed.  A fix is also 
needed in SimpleSubscriptionManager.publish() to first check if 
hasBeenShutdown() returns false immediately before calling 
NotificationProducerClient.notify(NotificationMessage[]).

The same issue seems to appear in SimpleNotificationProducer and possibly many 
other capabilities.  No cleanup is done in shutdown(), so calls to any other 
method after shutdown() can still succeed.

A solution to this is to add "sychronized" to both shutdown() and publish().  
This may not be necessary though as long as proper cleanup is done in 
shutdown(), and publish() and other methods do proper checks to ensure they 
don't do anything if shutdown() was already called.

I think to be safe in general, a caller should still check 
capability.hasBeenShutdown() before invoking publish() or other methods on the 
capability.


> SimpleNotificationProducer.getSubscriptions() returns a not-syncronized 
> collection
> ----------------------------------------------------------------------------------
>
>                 Key: MUSE-283
>                 URL: https://issues.apache.org/jira/browse/MUSE-283
>             Project: Muse
>          Issue Type: Bug
>          Components: WSN NotificationProducer
>    Affects Versions: 2.2.0
>         Environment: os: unix on solaris 
>            Reporter: Asaf Zafran
>            Assignee: Dan Jemiolo
>            Priority: Critical
>
> we have extended the SimpleNotificationProducer.
> in the method 
> public void publish(QName topicName, Element[] content, EndpointReference 
> consumer) throws SoapFault
> we have called the method:
> Iterator i = getSubsriptions().iterator();
> and the line 
> iterator.next();
> has caused a ConcurrentModificationException.
> the stack trace is :
> java.util.ConcurrentModificationException
>               at java.util.HashMap$HashIterator.nextEntry(HashMap.java:841)
>               at java.util.HashMap$ValueIterator.next(HashMap.java:871)
>               at 
> java.util.Collections$UnmodifiableCollection$1.next(Collections.java:1010)
>               at 
> com.cisco.nm.cmp.nbi.wsdm.server.notification.NotificationProducer.publish(NotificationProducer.java:182)
>               at 
> com.cisco.nm.cmp.nbi.wsdm.server.notification.NotificationProducer.publish(NotificationProducer.java:253)
>               at 
> com.cisco.nm.cmp.nbi.wsdm.server.wsresource.CommandCallback.publish(CommandCallback.java:256)
>               at 
> com.cisco.nm.cmp.nbi.wsdm.server.wsresource.CommandCallback.publish(CommandCallback.java:243)
>               at 
> com.cisco.nm.cmp.nbi.wsdm.server.wsresource.provservice.WorkflowCallback.gotResult(WorkflowCallback.java:92)
>               at 
> com.cisco.nm.cmp.nbi.mediator.core.CommandExecutor.setNotifyResult(CommandExecutor.java:270)
>               at 
> com.cisco.nm.cmp.nbi.mediator.core.MediatorOutputListener.callTranslator(MediatorOutputListener.java:379)
>               at 
> com.cisco.nm.cmp.nbi.wsdm.server.mediation.provisioning.workflow.run.RunWFResponseListener.notification(RunWFResponseListener.java:86)
>               at 
> com.cisco.nm.cmp.client.mediator.handlers.DefaultResponseHandler.handleJMSMessageObject(Unknown
>  Source)
>               at 
> com.cisco.nm.cmp.client.mediator.handlers.DefaultResponseHandler.handleJMSMessageObject(Unknown
>  Source)
>               at 
> com.cisco.nm.cmp.client.mediator.handlers.DefaultResponseHandler.handleJMSMessage(Unknown
>  Source)
>               at 
> com.cisco.nm.cmp.client.mediator.handlers.DefaultResponseHandler.handleJMSMessage(Unknown
>  Source)
>               at 
> com.cisco.nm.cmp.client.mediator.handlers.ResponseHandlerThread.run(Unknown 
> Source)

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


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to