In our current practice, we encapsulate the content of DQMH MHL events within subVIs to maintain a tidy diagram and especially to facilitate the seamless propagation of changes to similar projects that use the same implementation.
I think It would greatly benefit the DQMH framework if it could autonomously generate these subVIs as part of its MHL event scripting process.
As users of SVN for source code control, we rely on SVN-Locks to maintain a conflict-free development environment when collaborating with multiple project team members.
When working on DQMH Projects as a team, it would greatly enhance our workflow if we could selectively apply SVN locks to specific subsets of the project.
Currently, the DQMH scripting necessitates write access to the entire project, limiting flexibility in group collaborations.
Is it feasible to consider modifying this behavior to provide increased flexibility and efficiency for group work?
Most of the time we create multi-layer applications, and bottom modules need to share information that might have to cross several upper layers.
To avoid coupling and jumps between any non-adjacent layers, we have to create similar broadcast in the parent modules to repeat child broadcast one layer upper.
It would be interesting to have a utility that 'copies' an existing broadcast from one module into another.
And maybe have an option to code the forwarding :
automatically register for child broadcast in the parent if not done already
in the selected braodcast EHL case, map broadcast arguments onto parent broadcast VI inputs
I guess the same thing can be done when the communication needs to go down the layers, and therfore applied to requests.
In many cases I launch the cloneable instance(s) and launch the API tester on demand. In this case the API tester doesnt show if any instances are already running, I need to press the refresh button which I forgot in most of the cases. Other developer not that familiar with DQMH forgot it all the time causing confusion.
I have fixed this in the template module we use for cloneables:
We have identified that, if multiple clonable module instances are executed and a specific module (e.g. the first launched module) is stopped (no waiting) and afterward all open modules are stopped at once (incl. wait) the "stop module.vi" an error 1 is returning.
Steps to reproduce
Create a project and add a new clonable module
Create a tester VI and implement the code above
Run the VI and see error 1 at second Stop Module.
What is happening in the Background
Situation 1 - "Stall Data Flow" = 0
"Stop Module.vi" 2 runs into "Wait on Stop Sync.vi" and synchronizes stop over rendezvous. The acquired rendezvous size is 3 (Module 1 which is at stopping, Module 2 and Stop Module)
Module 1 is waiting in "Safe to Destroy Refnums.vi"
Module 2 runs into "Close Module.vi"
Last clone instance is fire at (1)
Releasing the Semaphore (2) will wake up module 1 that it is now safe to destroy refnums now. Module 2 runs into "Wait on Stop Sync.vi" (3) and synchronizes over rendezvous.
"Stop Module.vi" and Module 2 waiting for a third participation to join the rendezvous.
Module executes case to destroy Master reference.... and executes "Wait on Stop Sync.vi" (3) with no synchronization as the boolean "Wait for Module to stop?" is on false.
Module 1 executes "Destroy Sync Refnums.vi" (4) and is destroying the rendezvous.
Module 2 and "Stop Module.vi" will be release from the waiting of the rendezvous as the reference is now invalid and returning error 1.
Situation 2 - "Stall Data Flow" = e.g. 2000ms
In compare to the situation 1 the first module is already removed here. The obtained rendezvous has the expected size of 2.
When module 2 enters rendezvous synchronization in "Wait on Stop Sync.vi" (3) the expected amount of participant is reached, and the execution can continue.
In most of our tests, this situation worked fine and did not create an error.
For some situation, we had the behavior that shutdown of the first module seems to be faster as the wake-up from rendezvous of the second module. The module main of module 2 opened and showed error 1. Module 1 seems to destroy the references to early.
Situation 3 - First Module will be stopped with last "Stop Module.vi" call
The shutdown of a module is for this scenario delayed (add a wait 1000ms to exit case of the module)
Stop Module 2 waits for 11 rendezvous participations. (10 module and itself)
One of the previously closed module will destroy the synchronization events and makes the rendezvous reference invalid. => Error 1 at "Stop Module.vi"
The following screenshots are showing an extension of the "Stop Module.vi" and the "Close Module.vi".
The idea is to use a single element queue (SEQ) containing a map of sets. The key of the map refers to a "Stop Module.vi" which waits for stopping all module at the time when the "Stop Module.vi" is executed. The Set contains all Module ID's which should be stopped. Each module checks in its close condition if the SEQ is existing. If so, the module ID will be removed from the sets which containing the module ID. An empty set refers to all required modules have stopped and a notifier which is used for synchronization will be fired. Close Module.vi extention Stop Module.vi extention
With those extensions, all three described scenarios should be fixed. In addition, should it be possible to stop all module and launch in the background new ones, the stop and wait will wait until all those modules ID run at the stop execution are finished.
I added the project which the extensions and tests to the post.
Addition
I'm not sure, but I think that with the described change, destroy of the Module's Semaphore (1) should be done with the boolean condition of the First & Last Instance (2). (Red line)
Please let me know if you need any additional information and details.
Open the block diagram and find the event frame configured for this request (It might no longer be listed and instead say something like “Unknown Event (0x0)”).
Open the block diagram and find the event frame configured for this broadcast. (It might no longer be listed and instead say something like “Unknown Event (0x0)”.)
As mentioned in DQMH Forum: VI Reentrance issue VIs which are required to be non-reentrant are not reported from the DQMH validation tool if they were changed (e.g. to shared clone)
Some of the important VIs which should be reported:
When you create a Request and Reply event, the scripter creates such code in the MHL :
And I always end up refactoring it this way :
('Status update' related code can be ignored if it is a bit too much). Is it possible, using scripting, to directly script that so we don't have to do this each time ?
When validating a number of modules and going through the list of fixes, it's sometimes hard to keep track of what has already been fixed.
It would be nice to have some information on which failures were already fixed, and whether the fix was applied successfully or if there were errors or if there's a need for manual work.
I just put some icons into the screenshot to illustrate my idea - my feature request asks for a prettier implementation 😉
Currently the DQMH stock requests / broadcasts (eg: Stop module, Hide panel etc) are mixed with the user created requests / broadcasts so if one likes to check which requests, broadcasts etc are in the module he needs to open different subfolders and visually filter out the stock events.
This is a readability issue which makes it significantly harder to quickly understand (or recall) what events are available for the given module.
Possible solution:
Instead of mixing the stock DQMH events with the non-stock events create a virtual folder above all the virtual folders called "Module Specific" with subfolders like Requests, Broadcasts, Private and Controls and put everything the user create to there by default.
Big advantage of this of organizing the files this way would be that one could assume that whatever is module specific can be found in the these dedicated folders instead of spreaded somewhat randomly in the virtual folder structure of the module. I said somewhat randomly because the strucure as is currently is hard to read so developers try to make it more readable, everyone on his own way (eg: creating different folders, prefixing the user created events etc). So besides the increased readability of the module by applying this feature there is a very good chance that modules' structure will become more standardized across developers working at different companies.
I dislike using Clone IDs, Whenever I have used Clones in real life application, I always start by editing the Start Module VI and adding in a Clone name input. As I do this for all my clones the input name tends to be specific like 'Bay Name', or 'PSU Name' but a generic 'Clone Name' would be good.
I then pass that Clone Name into my MHL Data cluster in 'Initialize', each clone now knows it own name this allows things like
A Request to all Clones to get the instance for a name, so calling code can work in terms of Set Voltage(UUT_PSU), Set Voltage(RIG_PSU) rather than Set Voltage(45568) Set Voltage(40056), making a clone manager more code easier to read. -- I know this could be done in a clone manger with a Map or table, but I like the idea of the Clone know its own name.
As the clone knows it own name, because I gave it its name, this means clone instance configuration is easier, I have can have a single configuration ini file with each clone name as separate sections or I can have each clone read from its own ini file simple based on its own name.
Modules other than the clone manager can if needed talk to the correct clone using the name they do not need to know about the instance.
Thinking about this it would be, to my mind, a great feature addition to DQMH is by default there was a optional for providing a clone name at startup that was accessible as a Mod Admin property alongside the Module ID.
I want to be able to try to fix or poke the code more when an error occurs in the API Tester. The opportunity of going to the block diagram or attempting to send a different request goes away because the API Tester, by default, closes when an error occurs.
How I propose fixing it:
The first thing that I change on an API Tester at the first error is to remove the OR connected to the stop terminal in the loop and add an error indicator at the end instead of the Simple Error Handler and connect a local variable for the error. Would you please vote to have DQMH do this by default and have a validator to modify existing API Testers?
Current API Tester:
Proposed change:
Thanks,
Fab (yes, being the DQMH Lead Architect does not guarantee that all my wishes are turned into reality 😉 )
Find all while loops in the Main.vi of the specified module(s), and check if the DQMH Error Handler - Helper loop.vi is used to handle errors in each of the while loops, and flag it if not. Ignore the default EHL and MHL in this check.
There is an option to convert Requests to Request and wait for reply but requests can not be converted to Roundtrip, so a broadcast has to be created manually with payload identical to the Request. Creating a Broadcast is not much of a deal but having two identical payloads is not ideal especially if the payload bundles multiple typedefs.
Include a "checkbox" onto the Add New DQMH Module dialog panel that is labelled "Include a Helper Loop"
If the user checks this checkbox, a helper loop is automatically added to the Main.vi
The helper loop would not be a sub-VI, but simply a third loop on the main.vi block diagram.
A Wake up Helper Loop request is automatically created and included in a Private Requests virtual folder
Make the helper loop generic as per Sam's suggestion. My suggestion is to have three user events: 1) Timeout 2) <Stop Module> 3) <Wakeup Helper Loop>
Label the additional "Register for Events" node something different from the other "Register for Events" node, ie. DQMH_REG_EVENTS_HELPER_LOOP (so that the Validate tool does not raise it as an issue)
When generating a helper loop for new cloneable modules, ensure that in the "Wakeup Helper Loop" and "Stop Module" user events, that the Addressed to this Module.vi is used.