DQMH Consortium Toolkits Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Issue with preallocated reentrant VIs (with feedback nodes) in clonable modules

Clonable modules in DQMH are set to shared reentrancy, not preallocated. If you stop/destroy a module, but then create a new clone it might just fire up a previously active clone.

 

If this module calls VIs that are set to run with preallocated reentrancy and these have feedback nodes that need to initialize on load or first call the clone will not reinitialize those feedback nodes this time because the VIs were preallocated (and used/set their first call / load flag) when the shared caller was originally created, not when this new module was started...(or rather re-started due to its shared reentrancy).

 

This means that you have to make sure every module clone forces a reinitialization of such feedback nodes in the VIs it calls by other means (instead of relying on the clone and its subVIs to be unique copies with no prior state....). Or have I overlooked something (I have not spent much time on the issue yet as it just bit me at a very inconventient time... :-O)?

 

If correct, this can be quite tricky to get around/require a lot of extra code (although that is what I have done just now; moving feedback nodes out of the preallocated reentrant subVIs and moving the initialization to the out loop to be able to reinit on next launch of the module). Can clonable modules be set to be preallocated instead to overcome this (just setting a module from shared to preallocated does not do the trick though it seems), or how do you deal with it? 

0 Kudos
Message 1 of 4
(279 Views)

> Or have I overlooked something

 

The preallocated setting only applies to static subVI calls. This means that static subVI nodes dropped on the block diagrams of non-dynamically-launched VIs will be guaranteed to have their own, non-shared data spaces if the subVI is marked as preallocated reentrant.

 

Since cloneable modules are launched dynamically, the preallocated setting has no effect. This is true for DQMH cloneables, AF Actors, and any other entities in frameworks that support dynamically launched reentrant instances.

 

Put more simply, you'll see the exact same behavior you're describing with DQMH cloneable modules, regardless of whether they're marked as shared clone or preallocated clone.

 

I have occasionally run into the exact scenario you describe, and my solution is to ensure that cloneable modules always set any state to known values somewhere in the "Initialize" frame of the MHL. Which in my opinion is a best practice for any dynamically-launched code.

Message 2 of 4
(241 Views)

In the old days when reentrant VIs were more limited we cloned (dynamically launched a copy) by opening a reference to a template or physically copying the VI on disk and running it..So it was really a unique VI which really allocated new static (the preallocated reentrant ones) VIs to call (still useful today, for easier debugging e.g.)..

This is the behaviour I wanted and have (somewhat incorrectly then) mentally modelled with the preallocated reentrancy set on the dynamically called clones, but in reality it is not about that settings, but whether there is an Open VI reference triggered, an actual fresh copy is forced/allowed to be created or not...Which it is not in this case (DQMH framework etc); It only opens a VI reference to the clone when the first clone is made, after that it reuses that "master reference". One reason for this I guess is that later cloning does not risk being blocked due to root loop access. In my case the application is headless (runs as a service) so root loop blocking due to GUI-actions is less of a worry..

 

Having an option in DQMH to open new references when cloning instead of reusing the old "master reference" could be a solution. It would have to come with a warning that if this option is chosen cloning could be blocked by the root loop, but the advantage would be that each module and its static preallocated reentrant VIs would launch fresh.

0 Kudos
Message 3 of 4
(223 Views)

The DQMH designers opted for the 0xC0 option on Open VI Reference, which allows for multiple 'fire and forget' reentrant clones that can run independently when launched via Start Asynchronous Call. With this option there is no way to force new clones to be instantiated. In other words, the clone pool is *always* used. Note that this is the same approach taken by Actor Framework and multiple other LabVIEW frameworks, as it allows for the most flexibility and performance.

 

There is an option when launching a cloneable module to close the master reference:

initmod.png

 

The default for this is FALSE. Here is the text from the comment on the diagram of Init Module.vi explaining the purpose of this setting:

 

"The Close Master Reference parameter specifies whether or not the Master Reference used for launching clones will be closed when the module is shutting down.

 

If FALSE (default): The master reference will remain open even when the last clone shuts down. A future Start Module call will continue incrementing module ID values after the last one that was created. Your code will *not* be susceptible to root loop issues since Open VI Reference will only be called a single time, no matter how many times all the cloneable modules are stopped while Start Module.vi is running or reserved for running. You may see odd behavior if you are changing the 'run as singleton' value between Start Module calls.

 

If TRUE: The master reference will be closed. A future Start Module call will restart module IDs at 1. However, your code will be susceptible to root loop issues since Open VI Reference will be called any time you start a clone and the master reference was previously closed."

 

So it sounds like you would want this option to be TRUE, but even then, the closing of the master reference only happens when all instances of a cloneable module have been stopped. What you're asking for is a different launching mechanism, where a new master reference is always used. That would require changing the behavior of the framework in Start Module.vi, which is probably possible, but again, in my opinion, the better approach would be to initialize any state data in the 'Initialize' frame of your Main VI MHL.

Message 4 of 4
(147 Views)