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: Project Proposal: MultiCore MessageBus  (Read 4079 times)
lizardruss
Newbie
*
Posts: 9


View Profile Email
« on: July 03, 2008, 07:41:50 »

Hi All,

I have an alternative idea (and basic implementation) for communicating between modules. I have dabbled with j2ee web services and enterprise message buses before, and the problem seems similar. One service needs to talk to another, and to mitigate coupling between the services, they communicate via a Message Bus.

Here's a (hopefully) brief description of what I've implemented thus far.  I want to get feed back to see if this is a utility that could be contributed to puremvc.  I will use the utility regardless, but I wanted to contribute if possible.

The utility consists of the following classes:
MessageBus : Facades register themselves with this singleton class upon creation. In addition, facades will declare here what messages they are interested in, and optionally a transformer to translate the Messages into Notifications.

IMessageTransformer : interface that can be implemented to provide a way of transforming message types into notifications specific to each Module's ApplicationFacade.

MessageTransformer : a default implementation of IMessageTransformer.  This is added by default if no transformer is specified.


Here's an example of how to interact with the MessageBus in my current implementation:
:
override protected function initializeFacade() : void
{
super.initializeFacade();

// Setup message bus connection.
var messageBus : MessageBus = MessageBus.getInstance();
messageBus.registerFacade(NAME, this);

messageBus.registerTransformer(NAME, SessionMessage.LOGIN, new SessionMessageTransformer());
messageBus.registerTransformer(NAME, SessionMessage.LOGOUT, new SessionMessageTransformer());
}

And here's an example of sending a message
:
MessageBus.getInstance().sendMessage(new SessionMessage(SessionMessage.LOGIN));

The message bus receives the message, uses the module-provided transformer to transform the message into a notification specific to the module, and uses the module's facade to send it.

In this way, all messages sent are propagated as notifications to each Facade registered to the message bus.

The only coupling between modules is to the MessageBus, and to the Messages that will be shared between Modules of an application.

Let me know if this would be a valuable contribution to the project!
Russ
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #1 on: July 05, 2008, 02:09:56 »

Interesting stuff, Russ. I like the idea. A few thoughts...

ModuleA could register itself as the same name as ModuleB. Thus you have to have a scheme that makes the names of the facades unique, that each module developer must follow (similar to using a URI for an XML namespace declaration). This is only good inside a project where you control the whole namespace. If third parties are going to write modules, you can't control what they'll pass in as a name, and can't assume that they will be unique.

And it's also very safe since any actor in any module knowing or guessing the name of another module could easily retrieve its facade, and potentially access its data and services.

I'm always thinking xenophobically about inter-module communication. Consider a site like Wallop, for instance, where people are encouraged to write modules to plug into the pages of their Flex-based social app. Users can buy these 'mods' to decorate their pages. But what if they secretly snarfed personal data from the user's space and siphoned it off to evil-town?

Also adding a Singleton that every module has access to and calling it from within anywhere in any app could be a quick way to get a plate of spaghetti code.  To loosen the coupling of things, you want to shield as much of the app as possible from knowing anything about the fact that it is running as a module and that there is an uber-app being communicated with. Most of the app should be oblivious that there is an inter-module communication actor, and of the messages it uses. It should look as much like a self-contained app as possible.

I still think this is a pretty cool approach though, and would like to see how it pans out. I have 3 suggestions:

1) Instead of the facade telling the MessageBus what its name is, the MessageBus generates and returns a key on registration. The facade holds this messageBusKey. This way we have no issue with name conflicts.

2) Have the facade expose a sendMessage method that is the only place in the app that calls the MessageBus.

3) Decouple that from the rest of the app, by having a SendMessageCommand, which takes the notification that triggered it and creates the appropriate Message, and sends it by calling MyFacade(facade).sendMessage.

-=Cliff>


Logged
lizardruss
Newbie
*
Posts: 9


View Profile Email
« Reply #2 on: July 06, 2008, 01:58:51 »

Thanks for the feedback Cliff. I'll implement your suggestions and hopefully have some code + unit tests and a sample application in a couple days.

I've rethought some of my initial approach, borrowing the JunctionMediator idea from pipes.  Instead of having the facades themselves participate in sending messages, I've made an IChannelAdapter interface. This interface extends the IMediator interface, so that it can listen for Notifications.  Its sole purpose is to broker communication between the MessageBus and the Module/Application.

With this approach the only parts of the original application that need to be modified are the startup command (to handle creating the ChannelAdapter). Naturally the notification to message and message to notification logic will need to be implemented, but that's now part of the ChannelAdapter implementation. Once the channel adapter is in place, module to module and module to application communication should be transparent to the rest of the application.

The only thing that bothers me about this approach is that it is more difficult to send a message for a special case. Forcing one to send a notification just for the sake of sending a message doesn't seem reasonable.

For now I'll just create an IMessageSender interface that can be implemented by an application facade, command, etc. and hope a best practice comes out of using it more.
Logged
puremvc
Global Moderator
Hero Member
*****
Posts: 2871



View Profile WWW Email
« Reply #3 on: July 06, 2008, 06:07:33 »

The only thing that bothers me about this approach is that it is more difficult to send a message for a special case. Forcing one to send a notification just for the sake of sending a message doesn't seem reasonable.

Putting the logic to create and send messages into the ChannelAdapter and sending a notification to it would fully isolate the MessageBus communications. Encapsulation not only of the message sending facility, but of the message class itself would be optimum from a maintainability and reusability standpoint.

Lets say you have a Pipes based app but feel it's more complicated than what you need and want to switch it over to MessageBus. Or lets say you started with message bus because it was easier and later decide you want to switch to pipes as your app grows a little and it offers something you need. I think it's reasonable to expect both these scenarios to play out once the MessageBus utility is available.

So, if you're creating Pipes messages all over the app, then you have a lot of refactoring to do on to move to MessageBus and use MessageBus messages. If you're going the other way and you're creating a lot of MessageBus messages all over the app, you've got the same problem.

But if all communication with other modules is truly incorporated in one actor then it's a matter of switching the JunctionMediator for the ChannelAdapter, and giving the latter the same notification interests that the former had. That notification interests list codifies in one place all the known external communications.

-=Cliff>
Logged
Pages: [1]
Print