DQMH Consortium Toolkits Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

DQMH Broadcasts (Multiple Subscribers to One Module)

To me, maintaining the tree structure is not really about testing at all.  It's about reusability (by reducing coupling) and about making it easier to trace messages when debugging.  

 

Now the decoupling does make it much easier to test but to me, that is just a pleasant side effect.  With the tree structure testing requires launching any nested modules (or some sort of test double/mock for each) but it doesn't require launching any other part of the tree, which is nice.

 

As far as direct communication, if you are strictly following the tree model then there wouldn't be any at all.

 

However, there is another way that works well. If (in your example) the operator is simply forwarding a message that A broadcasts to B (via turning it into a request event of module B), another way to do it might be to have the operator send the A broadcast event refnum to B via a request event (of module B).

 

Why would you do that? for performance, readability, and coupling. 

Performance - the data is going directly from A to B and not being forwarded through the operator.

Readability - avoids extra code in the operator just for forwarding.

Coupling - B and A are not coupled as they wound be if you simply drop a Get Broadcast events from module A into module B.  In this case module B doesn't care where the event came from, it could be module A, it could be some other module.

 

 

Sam Taggart
CLA, CPI, CTD, LabVIEW Champion
DQMH Trusted Advisor
Read about my thoughts on Software Development at sasworkshops.com/blog
GCentral
Message 11 of 21
(1,479 Views)

Also if you were worried about B missing events, you could have the operator launch B first.  Then when it launches A before it synchronizes with A do a Request and Wait for Reply to forward the refnum to B. Then it is registered before A starts spewing events.

Sam Taggart
CLA, CPI, CTD, LabVIEW Champion
DQMH Trusted Advisor
Read about my thoughts on Software Development at sasworkshops.com/blog
GCentral
Message 12 of 21
(1,473 Views)

@Taggart wrote:

...have the operator send the A broadcast event refnum to B via a request event (of module B).


I like that!

 

YABA (Yet another broadcast approach 😉 ) is to have all your modules implement the same, standard broadcast event. We do so with a "System Message" broadcast that all our modules implement, so it's quite easy to register dynamically (again without static coupling).




DSH Pragmatic Software Development Workshops (Fab, Steve, Brian and me)
Release Automation Tools for LabVIEW (CI/CD integration with LabVIEW)
HSE Discord Server (Discuss our free and commercial tools and services)
DQMH® (The Future of Team-Based LabVIEW Development)


0 Kudos
Message 13 of 21
(1,469 Views)

Exactly! - static coupling is the thing to be wary of.

Sam Taggart
CLA, CPI, CTD, LabVIEW Champion
DQMH Trusted Advisor
Read about my thoughts on Software Development at sasworkshops.com/blog
GCentral
0 Kudos
Message 14 of 21
(1,460 Views)

small digression:

I am joining this party a little late (I was on vacation last week and I have been catching up)...

Thanks for everyone for participating in this discussion and keeping this corner of the forums alive even when I am not around.

 

Back to the main topic

 

The main idea behind a DQMH module was to have entities that could run by themselves (just click the run arrow on the DQMH Main.vi) or they could work with other code (calling code executes Start Module and Synchronize Events). We use events because they have the advantage that if the module is running by itself and it broadcasts events and nobody is there registered to listen to them, no memory leaks happen. In contrast, if we were using a queue, if the module is enqueuing things and there is nobody there to dequeue, then you have a memory leak.  

 

As Joerg pointed out we did not create the broadcast registration/synchronization with registrants in mind. However, we wanted to make sure that no events were lost. The calling code waits until the module has finished launching and is in the initialize case (meaning there were no errors during initialization and we are safely in normal DQMH module operation territory) and itself has registered to its own request events. By the time the code exits the synchronization, the calling code has the certainty that its requests will not be ignored and that it will not miss a single broadcast from the module.

 

I recommend checking out this blog post and presentation from GDevCon http://delacor.com/techniques-for-starting-your-dqmh-based-project/

 

It is hard for me to think in terms of A, B, and C. Do you have an example of what you are trying to solve?

 

Regards,

Fab

 

For an opportunity to learn from experienced developers / entrepeneurs (Steve, Joerg, and Brian amongst them):
Check out DSH Pragmatic Software Development Workshop!

DQMH Lead Architect * DQMH Trusted Advisor * Certified LabVIEW Architect * Certified LabVIEW Embedded Developer * Certified Professional Instructor * LabVIEW Champion * Code Janitor

Have you been nice to future you?
Message 15 of 21
(1,428 Views)
@Taggart wrote:

Exactly! - static coupling is the thing to be wary of.


Please let us be a bit more specific here, that sounds interesting.

If I drop Module B's Obtain Broadcast Events for Registration in Modul A this is static coupling, right? Because Modul A can't work without the presents of Module B.

Now you're talking about broadcasting an event refnum. I see it's dynamic, because the registration for broadcast will perfom at runtime. But...how?

 

I'll give a concrete example:Up and Down.png

Lets say I want to start my Data Provider. As it depends on the HAL it starts it and registers for its events. The same procedure does happen in HAL with the Config Module. But the Data Provider also wants to listen to Broadcasts of the Config Module.

 

My practice until now: As the modules are singletons I've dropped a Start Module in every Module in the upper tree, if the module wants to register for a broadcast of a lower module. So, my Data Provider starts the Config, the HAL tries it again, but then it is already running. It works without problems. Are the disadvantages of this design?

 

If the Data Provider wants to register for the broadcasts of the Config, how do I archieve this with dynamic coupling? How can I update the registration refnum in the EHL of the Data Provider? If the Config Module has a Broadcast "Broadcast Event Refnun Broadcasted" - How can the Data Provider listen to that Broadcast, if it is not already registered to its Broadcasts?

 


Proud developer at Hampel Software Engineering where we turn '404 not found' into '200 OK'. Join us on Discord
0 Kudos
Message 16 of 21
(1,405 Views)

What do the arrows represent on your graph?  Dependencies?  If so the thing to look for/avoid are circular dependencies, which it seems like according to your graph you don't have.

 

Key to avoiding dependencies - 

per your graph (assuming this is how you want your dependencies to look.)

Messages that flow with the arrow should be requests that belong to the module the arrow is pointing to.

Messages that flow against the arrow should be broadcasts of the module the arrow is pointing to.

 

That should limit your coupling.  The other things to watch out for though are typedefs that are part of a library.  Good idea to consider moving typedefs out of libraries unless it is only used internally to the library.

Sam Taggart
CLA, CPI, CTD, LabVIEW Champion
DQMH Trusted Advisor
Read about my thoughts on Software Development at sasworkshops.com/blog
GCentral
0 Kudos
Message 17 of 21
(1,394 Views)

@AlexElb wrote:

 

My practice until now: As the modules are singletons I've dropped a Start Module in every Module in the upper tree, if the module wants to register for a broadcast of a lower module. So, my Data Provider starts the Config, the HAL tries it again, but then it is already running. It works without problems. Are the disadvantages of this design?

 

 


That is the standard practice for Singletons and the reason why the Start Module.vi can be called from different places without worrying about who started first. 

For an opportunity to learn from experienced developers / entrepeneurs (Steve, Joerg, and Brian amongst them):
Check out DSH Pragmatic Software Development Workshop!

DQMH Lead Architect * DQMH Trusted Advisor * Certified LabVIEW Architect * Certified LabVIEW Embedded Developer * Certified Professional Instructor * LabVIEW Champion * Code Janitor

Have you been nice to future you?
0 Kudos
Message 18 of 21
(1,381 Views)

@Taggart wrote:

 

That should limit your coupling.  The other things to watch out for though are typedefs that are part of a library.  Good idea to consider moving typedefs out of libraries unless it is only used internally to the library.


I recommend creating a Shared.lvlib for the items that are shared among different DQMH modules. This is sometimes all you need to decouple two modules.

For an opportunity to learn from experienced developers / entrepeneurs (Steve, Joerg, and Brian amongst them):
Check out DSH Pragmatic Software Development Workshop!

DQMH Lead Architect * DQMH Trusted Advisor * Certified LabVIEW Architect * Certified LabVIEW Embedded Developer * Certified Professional Instructor * LabVIEW Champion * Code Janitor

Have you been nice to future you?
Message 19 of 21
(1,377 Views)

Yes, I noticed you did that in the DQMH CML example project.  It certainly does work.  

Sam Taggart
CLA, CPI, CTD, LabVIEW Champion
DQMH Trusted Advisor
Read about my thoughts on Software Development at sasworkshops.com/blog
GCentral
Message 20 of 21
(1,370 Views)