DQMH Consortium Toolkits Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Module to module dependency?

Hi,

 

as our project progresses I started to create more and more modules and I have started questioning myself if I have made the right decision with this. For example: I made a pretty simple module to log messages to a text file. At the time I wrote the module I thought it makes sense to make it a DQMH module (it has a GUI and some other requests beside simply adding a line to a text file) and anyways if I do something I do it in excess so I went down that route.

 

Now the problem is that in our team we use the functionality (I mean logging to file) at gazillion places, but as opposed to a traditional, super-simple, old-fashioned standalone logging VI now we have a DQMH module, so if you forget to launch it then you lose information. Which actually happens a lot, cause if somebody is just debugging a subset of the project (for example and instrument driver module which uses logging).

 

I can put the "Start module" VI of the logging module to the initialize case of the other module and then the "stop module" to the exit case. The problem with this is obvious: lets say you debug two modules at the same time both needs the logging module functionality. In this case stopping one of the modules will immediately stops the logging module and that could be an issue.

 

I see this now quite a bit of an issue and I'm wondering if there is any sort of an advice / best practice you guys have for me.

 

Thx!

 

ps: this meas that there IS a one-way dependency between our DQMH modules. I dont think this is ideal, but also dont think that its avoidable.

 

0 Kudos
Message 1 of 7
(1,502 Views)

Hello,

One solution to your issue is to use the `Module Was Already Running?` output of the `Start Module` function.

 

In the module that uses your log module.

You start your log module before entering the main case structure.

Pass the boolean value to the Exit case.

If True, you do nothing. the module was already running. You must keep it alive.

If False, your module has started the log module. You stop the module when you Exit.

 

You can glance at the CML project provided with the framework. The mechanism I described is used in the Acquisition module.

 

Hope this will help.

 

Olivier


Olivier Jourdan

Wovalab founder | DQMH Consortium board member | LinkedIn |

Stop writing your LabVIEW code documentation, use Antidoc!
Message 2 of 7
(1,479 Views)

We have similar requirements for most of our applications, which are usually built with our HSE Application Template

 

The DQMH modules will expect certain common resources to be instantiated and initialised when they execute: Our HSE Application class for paths and other basic info, our HSE Configuration class for, well, configuration, and our HSE Logger library for logging/debugging.

 

Usually, our application will start and take care of all the scaffolding (i.e. preparing all those common resources) before any DQMH module starts. When running DQMH modules directly and separately, we will start them from their corresponding API Tester, which will mimic the application and instantiate/initialise those common resources if they are not already in memory.

 

To solve this, we added a set of helper VIs to our HSE Libraries, which are themselves a common dependency to all our code. These helper VIs figure out if the required common resources are already started and in memory. If so, they do nothing. If not, they will start/stop the common resources as needed. 

 

Here are two screenshots taken from the API Tester of our "Dummy" showcase DQMH module in our HSE Application Template repo:

 

Bildschirm­foto 2023-01-06 um 18.22.24.png

 

Bildschirm­foto 2023-01-06 um 18.22.24 Kopie.png

 

The VI on the very left-hand side (\Source\hse-dqmh\DQMH Tester Prepare hse-appl.vi, part of our HSE Libraries) is quite trivial, actually: 

 

Bildschirm­foto 2023-01-06 um 18.33.44.png

All that code is open source, feel free to take a look at it.




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 3 of 7
(1,446 Views)

Thanks to both of you. Its good to know that this is a real problem and others faced that as well. For now I guess I will go with the rather simple solution Oliver suggested and later (maybe in our next project) I'll come back to the problem to see if there is a better solution.

0 Kudos
Message 4 of 7
(1,422 Views)

@Olivier-JOURDAN wrote:

 

You start your log module before entering the main case structure.


One additional thought about this (and one of the very rare cases - besides Zulip - where I disagree with Olivier): I would advise not to place any code outside the EHL, MHL or helper loops.

 

Or, more precisely - be very cautious about executing any of your code before the Synchronise Caller Events.vi inside the "Initialize" case has been executed. If said code takes too long, it will lead to a timeout when starting your module - the Synchronise Module Events.vi will return error 403683.

 

This error is very hard to track down, especially when the code you're executing grows over time and at some points takes too long (i.e. longer than 5 seconds). 

 

Edit: An alternative implementation is to start your module in the "Initialize" case - or any other case you call after starting the module - and keep the boolean value on the shift register.




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 5 of 7
(1,415 Views)

@1984 wrote:

Now the problem is that in our team we use the functionality (I mean logging to file) at gazillion places, but as opposed to a traditional, super-simple, old-fashioned standalone logging VI now we have a DQMH module, so if you forget to launch it then you lose information. Which actually happens a lot, cause if somebody is just debugging a subset of the project (for example and instrument driver module which uses logging).

 

I can put the "Start module" VI of the logging module to the initialize case of the other module and then the "stop module" to the exit case. The problem with this is obvious: lets say you debug two modules at the same time both needs the logging module functionality. In this case stopping one of the modules will immediately stops the logging module and that could be an issue.

 


Just a note, if you ever wanted to develop this, the technology that best allows it is a "Named Queue".  Don't use it as an actual queue, but use its lifetime behavior to determine the lifetime of your module.  Named Queues can have multiple references to them, with the Queue being created with the first reference, and destroyed when all references to it are released.  This allows you to make a Module that is started as soon as any other module wants to use it, and shut down when all modules using it have shutdown.

 

Non trivial to do, so I wouldn't necessarily advise it for everything, but a heavily reused logger might be a good use case.  

Message 6 of 7
(1,364 Views)

I do agree with you, Joerg. Avoiding code before the Synchronise Caller Events.vi is excellent advice.

In this specific use case, the nominal way to call the code should only call the broadcast events ref memory as far as the module has already been started. The actual module start will only occur when you test part of your code. It seems a reasonable trade-off for me in this specific case to keep simplicity in the code.

Anyway, the first rule should be: Do not call extra code before the module's initialization.


Olivier Jourdan

Wovalab founder | DQMH Consortium board member | LinkedIn |

Stop writing your LabVIEW code documentation, use Antidoc!
Message 7 of 7
(1,350 Views)