Jump to content

Message Routing Architecture


Recommended Posts

Hello Everyone

 

I've been following this thread intently and comparing the comments to a framework that Rob Humfeld, and his team at JET and I have been working on since the CLA summit. Rob presented an idea that he and his team were working on called the JAMA framework. I was able to video record the presentation and the next week when I got the code from Rob I dove in and began working with it. Since then we have made many refinements and used classes to make the framework more powerful.

 

Since this thread has discussed many of the issues that we have tried to design into the framework I thought this would be a good time to introduce it in its current version. At the CLA summit someone said that this framework was akin to an observer pattern. Since I wouldn’t know an observer pattern from a quilt pattern I will leave it up to others to decide what it is. I currently call it the Msg_Routing framework the fully tested version will come  from JET sometime later this year.

 

The framework has 4 major components Modules, Msgs, Couriers and Routers. There is a 5th component called Module Router but it is not necessary to use the framework

 

1. Modules are any vi that needs to sent and/or receive Msgs. To work within the framework the Module will need to create and manage a Courier and a Router for each Msg</li><li><font face="Calibri">2.      </font>Msgs is a defined data set that is transferred from one Module to another.   All child Msg class will inherit from the parent Msg class.</li><li><font face="Calibri">3.      </font>Couriers: An abstract class which is the Msg transfer mechanism by which the Module will receive messages. A Module will create a courier child class and register the class to receive Msgs. Child classes Queue_Couriers,Event_Couriers, and Notify_Couriers  are already a part of the framework</li><li><font face="Calibri">4.      </font>Routers: These hold the information that tell a shipping Module how to get it’s Msg to other Modules. A Router is created for each Msg and they share the same name. A Router is a named single element queue so all Modules can access the same routing data. The Router’s data is an array of Couriers.</li></ul><br><br>Framework features<br><br>Modules are totally autonomous and can connect and disconnect from the framework at run time without affecting other Modules. The Module is responsible for connecting and disconnecting to and from the framework and is not dependent on its caller for anything. Modules have no knowledge of each other only the Msgs they deal with.<br><br>Modules are responsible for creating and destroying their own Msg transfer mechanism called Couriers. One of the attributes that I have use from the Actor framework is that a Module is responsible for creating and destroying its Msg Courier. Callers no longer have to create a reference and pass it to the callee. <br><br>Msgs are Global in scope and are usable by all Modules. Any Module is allowed to ship or receive a defined Msg. Msgs and Routers are the only two things that connect Modules to each other making this framework very loosely coupled. <br><br>The Msg transfer mechanism or Couriers is abstracted. This allows one modules to use "Events" to receive Msgs and another to use "Queues". The decision to use Queues, Events, Notifies, or any other is made on a Module by Module decision and does not have to be a system wide constraint. <br><br>A Module must register for every message that it wishes to receive. To receive a Msg a Module must find the Router and place it’s Courier in the routers shipping array. <br><br>To send a Msg a Module gets the Routers shipping array for the target Msg and ships the Msg to each Module via its Courier. Data consistencyis maintained because Msgs are copied and sent to Modules not stored. <br><br>Here are some diagrams to help visualize the framework. They correspond to the demos in the attached code.<br><br> post-584-0-31639700-1310965017_thumb.png<br><br>post-584-0-03780300-1310965016_thumb.png<br><br><br>post-584-0-55132500-1310965013_thumb.png<br><br><br>post-584-0-88885900-1310965020_thumb.png<br><br><br>Developers<br><br>Module Developers only need to care about few things to work within the framework. What messages to receive, how those messages will be received and what messages to send. Developers can choose which method of Msg transfer works best for the module requirements by using a Courier child class that implements a specific mechanism. Only the Msg format is defined by the frame work how those Msgs are sent is up to the developer.<br><br> <br><br>Major Points<br><br>Msg transfer is completed without any kind of mediator loop.The Msg Router provides the information on how to send the Msg and the Module Shipping the Msg does the actual work.<br><br>Because it is the shipping Module that does the shipping and not another mediator loop, there is little loss in performance. <br><br>Modules are only coupled by Msgs and not the way in which they are transferred.<br><br>The full framework is attached complete with code, demos and images. It is written in LV 2010. <br><br>To start using the framework load the project and open the [Module Tree].vi all of the instructions are in the block diagram.The diagrams and instructions are inside the cases of the case structure.<br><br>Please let me know what you think of the framework good, bad or otherwise.<br><br> MSG_ROUTING.zip<br><br>Mark

  • Like 2
Link to comment

Wow, Mark, this is GREAT!

-- Rob Humfeld

Seriously, If you saw the JAMA presentation at the CLA Summit, I hope you take a look at this and provide some feedback in this forum.

If you didn't go to the CLA Summit, I hope you'll see this as one great reason why you need to attend in 2012.... and I hope you take a look at this and provide some feedback in this forum.

If you did go to the CLA Summit but did NOT see the JAMA presentation, then blink.gif... and I hope you take a look at this and provide some feedback in this forum.

A big thank you to Mark who took some ideas of his own and really enhanced the core JAMA concept.

Link to comment
  • 3 weeks later...

Modules are totally autonomous and can connect and disconnect from the framework at run time without affecting other Modules. The Module is responsible for connecting and disconnecting to and from the framework and is not dependent on its caller for anything. Modules have no knowledge of each other only the Msgs they deal with.

Msgs are Global in scope and are usable by all Modules. Any Module is allowed to ship or receive a defined Msg. Msgs and Routers are the only two things that connect Modules to each other making this framework very loosely coupled.

Question: what if I wanted two or more of the same module. Say, I wanted to make your "Waveform Module" reentrant and use it in two different ways in my application, with the "UI Module" interacting with Waveform Module A, and, let's say, "Simulated Temperature Readings" (STR) Module interacting with Waveform Module B. Is there a way to direct the messages to only the correct module (UI to/from A and STR to/from B)? If not, I would not be able to operate A and B independently, as they both act on start/stop messages from either of the other two modules.

-- James

Link to comment

Question: what if I wanted two or more of the same module. Say, I wanted to make your "Waveform Module" reentrant and use it in two different ways in my application, with the "UI Module" interacting with Waveform Module A, and, let's say, "Simulated Temperature Readings" (STR) Module interacting with Waveform Module B. Is there a way to direct the messages to only the correct module (UI to/from A and STR to/from B)?

If not, I would not be able to operate A and B independently, as they both act on start/stop messages from either of the other two modules.

I see two possible ways to approach this issue.

The first would be to create two separate Msgs for each, Start A and Start B.

When the reentrant waveform Module goes active It figures out which type of module it is A or B and then registers to receive only those Msgs.

The second would be to design one Start Msg with an enum that indicates the start type.

The waveform module would have to figure out it's correct start enum setting.

When the UI sends the start Msg it sets the enum to the correct type.

Both reentrant waveform module A and B receive the Msg but if the enum is not the correct type for that module it is ignored.

Both methods require that the module have some way of discovering what Msgs it cares about or what specific waveform module it is.

This will create some additional coding to make the module more intelligent.

The benefit IMHO is you have a very loosely coupled, more reusable, debug able, testable module.

Aside from the framework parent class dependencies, Each module is stand alone and totally independent of its caller or callees.

It's up to the module developer to figure out how to register, react and send the correct Msgs.

Hope this helps

Thanks for reviewing the framework

Mark

Link to comment

Both methods require that the module have some way of discovering what Msgs it cares about or what specific waveform module it is.

This will create some additional coding to make the module more intelligent.

The benefit IMHO is you have a very loosely coupled, more reusable, debug able, testable module.

Aside from the framework parent class dependencies, Each module is stand alone and totally independent of its caller or callees.

It's up to the module developer to figure out how to register, react and send the correct Msgs.

Have you considered adding some kind of optional local scoping to your framework? Sort of a "local router subnet". If you had the option of specifying a local scope when registering to send or receive a specific message (such as string like "UI subnet") you could easily set up an arbitrary number of Waveform Generators under different scopes, communicating independently with different modules, without needing to extend the code of any module. Local scoping could also increase the flexibility of your framework, allowing more hierarchal "module-submodule" relationships in addition to stand-alone modules.

-- James

Link to comment
  • 1 year later...

When I download the ZIP my LabVIEW 2012 is having trouble locating the "NetworkStream_InterTarget_Courier.lvclass", is anyone else having this problem? I found a file called "NETWO~1.LVC" in the location that this file is suppose to be in but even after renaming LabVIEW is still not happy.

Edited by cme0848
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.