Futurescale, Inc. PureMVC Home

The PureMVC Framework Code at the Speed of Thought


Over 10 years of community discussion and knowledge are maintained here as a read-only archive.

New discussions should be taken up in issues on the appropriate projects at https://github.com/PureMVC

Pages: [1]
Print
Author Topic: [ ANTIPATTERN ] Possible Problem with removing Mediators  (Read 12912 times)
huesforalice
Newbie
*
Posts: 1


View Profile Email
« on: February 11, 2008, 08:57:00 »

Hi there Cliff,

first of all thanks a lot for sharing your great framework with us.

I've recently come across a problem I wanted to let you know about. Possibly it won't occur if one doesn't violate best practices advice, I'm not good enough a programmer to tell yet ;).

Here's what I've come across. If a notification is sent that a few observers are listening for, and this notification involves removing mediators which are actually also listening for that same notification it can happen that some of the observers won't hear the notification.

Consider this function in org.puremvc.core.view.View
:
public function notifyObservers( notification:INotification ) : void
{
if( observerMap[ notification.getName() ] != null ) {
var observers:Array = observerMap[ notification.getName() ] as Array;
for (var i:Number = 0; i < observers.length; i++) {
var observer:IObserver = observers[ i ] as IObserver;
observer.notifyObserver( notification );
}
}
}

One by one all observers are notified. If, say, there are 6 observers listening, and the 3rd observer responds to this notification sent, by removing the 2nd observer, the array will be shortened by one observer while the for-loop is still running. So all the indizes after the 2nd observer will be decreased by one thus causing chaos in the array. In this example the observer at the 4th position in the array will be moved to the 3rd position and miss the notification.

I hope I made myself clear, haven't had time to provide any samplecode up to now, but can if what I'm saying is not understood. My work-around is to make an exact copy of the observer array before entering the for-loop and using that. That way I can be sure that no observer will be missed. On the other hand removed observers will still be getting this one last notification which they actually shouldn't.

Thanks again for your great work, hopefully I've helped somehow to improve it.
« Last Edit: February 25, 2008, 03:39:20 by puremvc » Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #1 on: February 11, 2008, 11:30:09 »

Hi,

I understand the problem.

It will only occur if the removed mediator is before the iterator position as you described with the third removing the second causing the fourth to fall back to the third position, thus being skipped when the iterator is moved to 4.

If the removed mediator is after the iterator position, then there is no problem, those after it fall back one, but the next one to be evaluated is still the next surviving mediator to be notified and all is well.

Copying the array and iterating through the copy so that every registered observer for the notification is in fact notified seems like the correct thing to do in this case.

However:

I still need to understand the rational real world design that would have one mediator signed up to receive a notification and act on it, while another mediator acts on the same notification by removing the first. And yes, you have to wonder, was the removed mediator supposed to be notified or not?

If there is a real problem here that people applying ordinary sensible practices are likely to fall prey to I'm all about fixing it. But when it comes to actually making a framework change to fix the problem, we need to understand its causes and the expected behavior better.

For instance if the 3rd mediator to be notified removed the second one then the second one was already notified before it was removed. If it's not supposed to be notified then you need to more carefully manage the order of registrations and make sure it's after the killer mediator in the observer list for the notification in question.

But managing the order of the observers in the list is not really something one can be expected to do in a system that does a lot of dynamic register/unregister activity.

Which leads us right back to the to the idea that having one notification be acted upon by multiple mediators, one of which removes the other as a result just doesn't make a lot of sense.

Can you post a scenario that evidences this problem and describe why there is no other approach that makes sense?

Otherwise, I'm inclined to file it under oddities/anti-patterns.

Thanks,
-=Cliff>

Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #2 on: August 14, 2008, 03:40:30 »

See http://forums.puremvc.org/index.php?topic=490.0 for the resolution to this problem which also happened in the more reasonable circumstance of:

Multiple mediators responding to the same notification by removing themselves.
 

As opposed to one mediator removing the some of the others that are signed up for the same notification, which is still an anti-pattern.
Logged
Pages: [1]
Print