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.
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:
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)”.)
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 ?
This is more of a question or request for comments than an actual feature request:
In the dialogue window for creating a new DQMH module, should we rename the caption "Module Type" to "Module Template"? For a vanilla installation of DQMH, there are only two templates to choose from (Singleton and Cloneable), so the caption makes sense. Once you start adding your own templates, not so much anymore. Also, for documentation purposes, it would make things clearer if we separated the term "type" from the term "template".
In addition, it would be nice to see the actual type of the module (singleton or cloneable) added to the name in the dropdown list (see screenshot).
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.
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 😉 )
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:
By default, in the MHL Error case, the "error out" local variable is written to. But the error that is written is NOT the error that came into the MHL Error case!
I propose the above be changed to this:
By doing this, the actual error that was raised by the module will be copied to "error out"
In the Create New DQMH Event... dialog panel, add a checkbox and label it "Make this a Private Request".
If this box is checked, the DQMH tools would create the request as normal, but store it under a virtual folder called "Private Requests" (Access scope = private)
When working with helper loops in cloneable modules, it would be nice to have a way for sending messages from the MHL to the helper loop which doesn't need the module ID, and which doesn't interfere with other clones' helper loop timings. I'd still like this new mechanism to look and feel like the regular events, with all the scripting and other goodness.
Maybe instead of calling them private events, a better name would be "local" events (which would, of course, be set to private scope).
Reviewing somebody's DQMH code I noticed an error generated in the exit case where they had cleanup code (1) was not captured by the Tester. This is purely because the exit case causes the MHL to terminate (2), so the normal error handling strategy (3) doesn't work (enqueuing another job called Error). Can I propose, unless there's a better technique, that adding the "Error Report" broadcast at the end of the Exit case (4) is a simple way to ensure any errors generated here get reported.
Hi, I would suggest adding a boolean called 'Include Dependencies' to the function on the scripting API to search for DQMH modules on the project, sometimes we have projects and we call DQMH Modules not listed on the project itself, but the developer should be aware we are calling those DQMH modules under dependencies, the Panther Dashboard for DQMH already is searching for DQMH modules under dependencies but it would be great if the native function does this functionality, also, I suggest adding a boolean array output to know if the resulting modules are located under dependencies or they are in the project.
This is how I visualize the connector pane of the 'Get DQMH Modules in Project.vi'
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.
The below image comes from the Error Reported broadcast event case in the API Tester (as found in the default Singleton or Cloneable DQMH module templates):
This produces strings that look like this:
This could be improved by adding the "message" component of the error, by using the Simple Error Handler.vi. Using the message makes the error report more descriptive, and doesn't rely on the user having to use "Explain Error" to review what the error code's could possibly be related to.
This produces strings that look like this:
Observe that the error message is now present in the text.
We are constantly having deployment errors on RT targets, mentioning the Simple Error Handler. Since on RT Targets that function is useless anyway, we've put a conditional disable structure around. This solved the error.
It would be nice, if that CDS would be added to a standard DQMH module.