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: [ FIXED ] Unexpected behaviour when registering the same mediator twice  (Read 23986 times)
gabon
Jr. Member
**
Posts: 14


View Profile Email
« on: April 07, 2008, 04:02:25 »

I noticed that if, maybe for mistake, I register the mediator twice, it will respond twice to the same event. I can agree that registering the same mediator twice shouldn't happen, but I was expecting eventually an error or ignoring the registration.

I'm using version 2.0.3.

Cheers, chr
« Last Edit: August 14, 2008, 03:35:08 by puremvc » Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #1 on: April 07, 2008, 06:25:04 »

Yep, you're right.

You'd only have one key in the View's mediatorMap, but an extra Observer would be created. Controller.registerCommand has logic to handle this for Commands, but the View needs it as well.

It shouldn't be hard to fix this. It may be later next week before I can get the fix in place, though.

-=Cliff>
Logged
Bill_BSB
Jr. Member
**
Posts: 13


View Profile Email
« Reply #2 on: May 14, 2008, 08:03:05 »

Hello guys,

this my first post ever on the PureMVC community. I hope that I can contribute positively with the community.

Now, to the strange stuff:
This behavior also happens with notifications. Each instance of the IMediator added in the facade, responds to the notifications that it has interest. I noticed it by some strange behaviors that were occurring:
 1- The method facade.removeMediator(MyMediator.NAME) wasn´t removing properly the specified mediator because when I call it, the mediator is still there and responds to notifications. Or maybe is something wrong with the observers. I don´t know yet.

 2 - The method facade.registerMediator(new MyMediator.(viewComponent) ) works fine. But I suddenly noticed that there where lots of extra instances of a Mediator that I didn´t need because of the new syntax. When I first started to user the framework, I thought that the registerMediator() method only registered one instance of a mediator by it´s name no matter if I used new or not. The solution I came up was using the Singleton pattern for my Mediators. Now I use this syntax for my apps: facade.registerMediator(MyMediator.getInstance(viewComponent) ) and now I´m sure that it will be only one instance of my mediators registered in my Facade.

Well, thats it. I hope this hint helps other folks. And please, if there´s another way for solving this, or if you noticed that I´m using the wrong commands/syntax, tell me!

See ya
Logged
Bill_BSB
Jr. Member
**
Posts: 13


View Profile Email
« Reply #3 on: May 14, 2008, 08:12:17 »

Oops, forgot to mention that I´m using the latest version of the Framework: 2.0.3.

I saw a lot of other posts concerning this strange behavior and I´m reading all of them to see if there was a already a solution posted.


I hope my solution´s handy for someone.

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



View Profile WWW Email
« Reply #4 on: May 14, 2008, 03:13:06 »

What new syntax was causing the creation of unwanted instances of your mediators?

-=Cliff>
Logged
Bill_BSB
Jr. Member
**
Posts: 13


View Profile Email
« Reply #5 on: May 15, 2008, 11:48:44 »

Hello Cliff,

This syntax: facade.registerMediator(new MyMediator(viewComponent) )

It´s when I instantiate a new Mediator in the arguments of the registerMediator method. It make sense to me since I´m creating a hole new instance of a class. The only thing I didn´t know is that the method really register the mediator even if there exists another instance, registered, of that mediator´s class.

I´m trying a new test code here and later I´ll post it the result behavior.
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #6 on: May 15, 2008, 04:03:56 »

So the multiple registration was due to your code calling the registerMediator method multiple times with a Mediator that returns a constant for its name rather than a unique value.

But the framework, as this thread asserts, should stop the extra Mediator instances from being registered unless they have unique names. I think the framework should throw an exception if you try to register a Mediator by a name that has already been registered.

Ignoring the new registration is failing silently, and you'd never know that your bad code was trying to register a mediator by the same name more than once without removing the other Mediator first.

By extension this is probably true of inadvertent multiple registration of Proxies and of Commands. Although Commands aren't such a problem because they aren't instantiated until they are executed. This means there's no zombie objects left floating around. The errors force you to solve the problem that's causing the spurious extra registrations.

-=Cliff>
Logged
zilet
Courseware Beta
Jr. Member
***
Posts: 17


View Profile WWW Email
« Reply #7 on: May 16, 2008, 01:52:49 »

This is happening because mediator is not unregistered form the observers list. So it is still there even if you call the removeMediator, the same thing stands for Commands.

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



View Profile WWW Email
« Reply #8 on: May 16, 2008, 05:44:51 »

The problem doesn't exist for commands anymore, though it used to be the case.

-=Cliff>
Logged
Bill_BSB
Jr. Member
**
Posts: 13


View Profile Email
« Reply #9 on: May 16, 2008, 11:33:29 »

Nice replies!

Here is my final, hopefully, fail safe code for managing mediators. Just to remember that the main idea is to have the fewest possible mediators registered at a time so they are registered and removed from the facade often. I want to reduce my Observers list so it can be scanned faster.
:

// Remove unused/unnecessary mediators first
facade.removeMediator( MyOtherMediator.NAME );

// If there´s no instance of MyMediator.NAME registered in the facade, get a instance and register it!
if( facade.hasMediator( MyMediator.NAME ) == false )
    facade.registerMediator( MyMediator.getInstance( viewComponent ) );


Now, not only I am sure that there´s only one instance of mediators, due to the Singleton Pattern, I´m sure when to register them or not!

Please, advise me if my thinking is wrong or bad or unnecessary .

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



View Profile WWW Email
« Reply #10 on: May 16, 2008, 04:48:24 »

@Bill, This is certainly a valid workaround.

@zilet, To clarify, it isn't that the Observers associated with Mediators aren't removed from the Observer list categorically. It is that an extra one is registered when you 'overregister' a Mediator, registering it twice with the same name. If you remove it it will only remove one Observer. Because it didn't check that the registration was in place before overwriting the key in the mediatorMap.

-=Cliff>
Logged
zilet
Courseware Beta
Jr. Member
***
Posts: 17


View Profile WWW Email
« Reply #11 on: May 17, 2008, 09:43:14 »

Nice workaround indeed.
Yes now we came to the end to the bottom of this one!

Greets!
Logged
Bill_BSB
Jr. Member
**
Posts: 13


View Profile Email
« Reply #12 on: May 20, 2008, 03:09:24 »

Thanks guys.

I´ll try to make a good "Singleton Mediator" manager class, or add-on, or something or whatever.  ::)

Now I´m facing a hole new challenge with mediators and States!

See ya!
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #13 on: May 20, 2008, 03:56:12 »

Rather than go to the complexity of adding such a manager, why not just do this whenever you want to make sure your Mediator hasn't already been registered:

:
if ( ! facade.hasMediator(MyMediator.NAME) ) {
    facade.registerMediator(new MyMediator(viewComponent) );
} else {
    facade.retrieveMediator(MyMediator.NAME).setViewComponent(viewComponent );
    sendNotification(DEBUG, 'MyMediator already registered!');
}

The Mediator should not be stateful. The componet itself can be, but maintaining state for a component is not a responsibility for the Mediator. Therefore, swapping out its view component dynamically with a new one should not be a problem.

Making a Singleton Mediator or using a solution like the one above to keep more than one instance of th e Mediator from being created and registered can be indicative of questionable notification / state management practices elsewhere in the code.

This is why I believe the above patch is a better answer. It helps things work properly while you track down the reason it's being called more than once in the first place.

Cheers,
-=Cliff>
« Last Edit: May 20, 2008, 03:58:01 by puremvc » Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #14 on: August 14, 2008, 03:44:12 »

Fixed in 2.0.4. A new unit test proves the fix, and will fail on prior versions of the framework.

See the release notes here: http://trac.puremvc.org/PureMVC_AS3/wiki/ReleaseNotes

-=Cliff>
Logged
Pages: [1]
Print