DQMH Consortium Toolkits Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Helper Loop and cloneable modules

Solved!
Go to solution

Hello everybody,

 

first of all thank Delacor for offering the DQMH Framework. I started developing with Labview half a year ago and found your framework two months ago. Until now it works like a charm and I'm very happy with it. From time to time I found myself wondering how things work out, but mostly I found something online, e.g. joergs blogpost about helper loops which helped me a lot. Now to my question.

 

I've build a cloneable module with a helper loop. This modul has two private requests to wake up and set to sleep the helper loop. Now what happens is, that this private requests from clone A wakes up / sets to sleep clone B's helper loop. Shure, the event is the same, and I didn't think about that before.

 

Now what I would do is to add the moduleID in the private requests. In the helper loop  I would then create a case structure and use the Addressed to This Module.vi like it is used in the EHL. But wouldn't it be much nicer, if the event in clone B doesn't get fired at all, when clone A is doing something?

 

How are you solving that issue?


Proud developer at Hampel Software Engineering where we turn '404 not found' into '200 OK'. Join us on Discord
Message 1 of 32
(10,038 Views)

Hey Alex, 

 

happy to hear that the online resources were helpful to you!

 

By design, DQMH creates one set of events for any module, be it singleton or cloneable. Depending on how exactly your helper loops work, that could be a problem. Every time you call the Start Helper or Stop Helper Loop, all of the clones will leave the "wait for timeout" state and execute the corresponding case. That means that your timeout counter is reset. 

 

If you rely on the helper loop's timing in such a way, you have to create some other, local communication channel. If your timing works differently, it might not do much harm to send the DQMH event and just discard it in all but the addresses modules.

 

Hope that helps!

 

Cheers, J.

 

 




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)


Message 2 of 32
(10,009 Views)
Solution
Accepted by topic author AlexElb

@AlexElb wrote:

first of all thank Delacor for offering the DQMH Framework. I started developing with Labview half a year ago and found your framework two months ago. Until now it works like a charm and I'm very happy with it. From time to time I found myself wondering how things work out, but mostly I found something online, e.g. joergs blogpost about helper loops which helped me a lot. Now to my question.


Hi Alex,

Glad to know that DQMH is working out for you. 

 


@AlexElb wrote:

 

Now what I would do is to add the moduleID in the private requests. In the helper loop  I would then create a case structure and use the Addressed to This Module.vi like it is used in the EHL. But wouldn't it be much nicer, if the event in clone B doesn't get fired at all, when clone A is doing something?


If using the Addressed to This Module.vi is not enough for your case, meaning you are waking up and putting to sleep the helper loop events at different times and your code cannot cope with the disruption, then you can create a local event then. Instead of relying on the Private wake-up helper loop and set to sleep helper loop, create a local pair of events. To do this, you can create your events directly in the DQMH Main.vi. The picture below shows the creation of the local helper loop events, the MHL firing the Wake up Helper Loop.vi and the destruction of the local events outside the event handler loop. Note that you have to pass along the user event references because these events only exist in this block diagram. 

 

 

Local Cloneable Module events.jpg

The code inside the Create Local Request Events.vi, Destroy Local Request Events.vi and Wake up Helper Loop.vi is in the image below together with how I would structure the code inside the cloneable module library.Local Cloneable Module Events implementation.jpg

I hope this helps.

 

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 3 of 32
(10,005 Views)

Hi Alex,

 

Not sure if I am over-simplifying here, but here is how we handle this in a clone...

 

1 - The Wakeup Helper Request VI has the module ID passed in as an argument.

2- Then in the Helper Loop, it checks that the module id was addressed and decides whether to wake up or not.  This approach works for us.

 

helper loop.png

Christopher Farmer

Certified LabVIEW Architect and LabVIEW Champion
DQMH Trusted Advisor
https://wiredinsoftware.com.au

0 Kudos
Message 4 of 32
(9,988 Views)

@Ozfarmboy wrote:

Hi Alex,

 

Not sure if I am over-simplifying here, but here is how we handle this in a clone...

 

1 - The Wakeup Helper Request VI has the module ID passed in as an argument.

2- Then in the Helper Loop, it checks that the module id was addressed and decides whether to wake up or not.  This approach works for us.

 

helper loop.png


I agree with you Chris, this is the way we go too and for the majority of our applications this approach works just fine. 

 

I believe Alex said he was already doing that (his words: "In the helper loop  I would then create a case structure and use the Addressed to This Module.vi like it is used in the EHL. But wouldn't it be much nicer, if the event in clone B doesn't get fired at all, when clone A is doing something?" 

 

The only reason I would go with the solution I proposed above was if the problem he might be having is that anytime any of the clones fire the private wake-up helper loop event, any event structure that is registered for the cloneable module events and is handling the wakeup helper loop will get their structure timer restarted. Since all of them share the same code, we know that all of them are going to have their Wake up Helper Loop event case executed, and the timer for that event structure will be reset, even if the event case decides "this event is not addressed to me". 

 

This is not an issue if your application is always waking up all of the cloneable instance helper loops and putting them to sleep all at the same time. But if you had an application where they are starting and sleeping at different times, this might be an issue. Or if you have one particular clone instance that keeps waking up and going to sleep at a very high rate, none of the other clones would get their timeout event case to execute.

 

This is definitely a corner case and I would go with your approach 99% of the time.

 

Thanks for contributing to the conversation.

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?
0 Kudos
Message 5 of 32
(9,982 Views)

If you really wanted to cover all your bases couldn't you just unregister for the Wake Up Event Once you have been woken up?  And then when you put to sleep just reregister for it.

 

Although then I guess when you are in the active state you need to stay registered for the sleep event so another clone getting a sleep event would mess with the timing.

 

Perhaps just doing the "local" events is the way to go.

Sam Taggart
CLA, CPI, CTD, LabVIEW Champion
DQMH Trusted Advisor
Read about my thoughts on Software Development at sasworkshops.com/blog
GCentral
Message 6 of 32
(9,977 Views)

Hey all together,

 

thank you all for your suggestions.

 

Thank Joerg specifically for poiting out that the clones will leave the "wait for timeout" state! I thought my problem of one clone affecting another clone would be gone, if I just use the Addressed to This Module.vi in the helper loop - but it isn't, because I was relying on the timing of the timeout case. After rereading your Update from 2018-02-12 on your mentioned Bloqpost, yeah well - you had already said it. But I would suggest to make it more clear that clones may call events and thus affect the timeout case from other clones. At least for me as a beginner this wasn't clear. I should learn not to rely to much on a framework - or better: one should really understand the used techniques.

 

Wow Fab, the local Events for the Helper Loops should do the trick exactly as I need it. I'll try it out later. If I undestand it correct the local events  from clone A couldn't call any event structures of clone B - so there should be no way of influencing. Further more, if I inspect the clones with the Event Inspector I would only see local events from that specific clone. Perfect! Couldn't you please build in a scripted feature for creating local events? 😉

 

Christopher, as Fab already stated, I am already using that approach. Now the problem is not, that clone A wakes up clone B, but that clone A has set a Timeout and clone B wakes up, the Timeout from clone A isn't correct anymore, because an event has occured in the meantime.

 

I have attached my test project to ilustrate the problem, maybe it is interesting for others:

The cloneable in the Start Help Case takes a "waiting time" parameter and wires it to the timout. When the timeout is reached, it makes a broadcast, that it has "perfomed it task" and stopps the helper loop. This works like a charm, if you only have one clone running and i was using this as a timer module to realise a duration alarm for one modul, which should log data every 5 minutes...

 

In the Tester VI I have added code to

- start 100 clones

- start test (the first 10 clones should wait 10 s, the second 10 clones should wait 9s and the last clones 1 second)

- evaluate test (calculate how long a clone has waited)

 

There it is obvious, that the clones don't wait as long as the should, since they wake up in the meantime several times.

 

Sam, jup, the helper loop must at least be listening to the sleep event, so we can't unregister from that.

 

 

Edit:

I've implemented the local request events and added the new version as an example. I did it quick and dirty, because it was just to test for me, but maybe someone wants to have a look at it. Thanks again Fab, it works as expected, pretty cool! And I learned something about how to work with user events.


Proud developer at Hampel Software Engineering where we turn '404 not found' into '200 OK'. Join us on Discord
Download All
Message 7 of 32
(9,962 Views)

AlexElb, you're right, the blog posts should address this more explicitly. I've updated both

 

Thanks for pointing that out!




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)


Message 8 of 32
(9,922 Views)

@FabiolaDelaCueva wrote:

Note that you have to pass along the user event references because these events only exist in this block diagram.

 

 

After implementing your approach, I wonder why it is not possible to create a VI which holds the specific local events of a clone, just like the DQMH does it for a normale module. I did try it and it is not working - but I don't know why 🙂 I configured this VI to be Preallocated clone reentrant execution:Obtain Local Requests EventsObtain Local Requests Events Of course that would be more elegant than wiring the user event references around everytime...


Proud developer at Hampel Software Engineering where we turn '404 not found' into '200 OK'. Join us on Discord
0 Kudos
Message 9 of 32
(9,910 Views)
Solution
Accepted by topic author AlexElb

A comment: there is no particular reason that you have to use similar communication techniques for "helper" loops as you use between Modules, and there is an advantage in using comms that are inherently (and obviously) encapsulated inside one Module.  Also simpler.  Here is a quick demo of a Channel-based helper loop, with adjustable timeout:

Helper with Channels.png

Message 10 of 32
(9,903 Views)