LabVIEW Idea Exchange

cancel
Showing results for 
Search instead for 
Did you mean: 
drjdpowell

Means to register a DVR-cleanup callback fior use when DVR released when VI goes idle.

Status: New

DVRs are references, and are automatically released when the VI hierarchy that created and "owns" it goes idle (stops executing).  Commonly, the DVR just contains by-value objects, or LabVIEW references that are also automatically released, but an important use case of DVRs is wrapping a non-labview reference that must be properly cleaned-up.   An example is an SQLite Connection pointer that must have a dll method called on it in order to release the database file it is holding open.  Many dlls have similar pointers/handles that need to be properly closed.  This is a headache for Programmers, who cannot rely on a stopped VI releasing its resources, often requiring restarts of LabVIEW to unload the dll.

 

A clean and easy solution to this problem would be to allow a "DVR Cleanup Callback VI" to be registered with the system when the DVR is created.   That VI would be called if and only if the DVR is release because its calling VI hierarchy goes idle.   This VI would contain the code to cleanup/close the contained non-LabVIEW references.  Could have other uses, such as debugging. 

 

I have developed multiple APIs that wrap non-LabVIEW dlls, and this feature would be a very significant help.   Please consider it.

18 Comments
drjdpowell
Trusted Enthusiast

All I want is a way to call some simple clean up code so that Users of my API don't have to worry about clean up.  I want my API to be like an in-built LabVIEW reference.  The application-code User does not need to debug it, and "Abort" to that User means abort the application.   If I, the API developer, can't "Abort my abort" or have to get fancy to debug the callback, I happy with that.  

 

>what do you do about the Abort button?

Call the callback, just like any LabVIEW reference.  That's the entire point.  This is not Application code.  Always cleaning up when the VI stops, without fail, is the entire point. 

 

>And the scripting Abort method would need an input for whether to abort or not

Call the callback, always.   No input, no choice.

 

>If the cleanup VIs always run when aborted then how do you abort >the (likely-running-in-the-background-without-their-panels-open) cleanup >VIs themselves? Double click the abort button?

What?  Bending over backwards with background daemons is the massive overcomplexity I want to avoid with simple callbacks.   Most of these callbacks would need to do little other than make one dll call.  With an SQLite Statement object, for example, it is just SQLite3_Finalize.

drjdpowell
Trusted Enthusiast

 >Are those refnums still valid when the cleanup VI for the outer DVR runs?

 

I don't want the complexities of complicated uses to detract from the very high value of very simple uses, but..., could one call the  callbacks in reverse order of DVR creation, before the inbuilt cleanup?

 

>because those are frequently used as lookup keys in registration tables

 

Again, this seems way over complicated for typical use cases.  I just need to clean up and disappear.

AristosQueue (NI)
NI Employee (retired)

Powell: Your goal and mine are the same, but I don't think these issues are all that advanced.

 

I don't think we can dismiss the Abort issue so easily. All it would take is one DLL that wasn't quite set up right and a user is completely hung in a VI they can't stop. They would have to kill LV and lose all unsaved work. That seems like a nasty trap to drop someone into. But how about this... we unconditionally call the cleanup VIs, but after caller is aborted, we wait a suitable delay, and if the cleanup VIs aren't done, throw a dialog for "Abort cleanup VIs? [OK] [Cancel]". That seems to provide the best of both worlds -- an unconditional cleanup call and an escape valve.

 

The lifetime issues don't seem very advanced for me -- they're pretty much the only times I've ever had a need for such cleanup. For example, the refnum used as a lookup key is pretty common as a way to track related entries in databases, or to unregister from some service that was sharing the refnum (my use case). And I never need to clean up plain LV data... what I usually need to clean up is some system thing that the DVR was managing, which is some other refnum type.

 

 You mention unloading in reverse order. At first I thought that wasn't well defined, given a parallel language, but any given DVR could be registered before it could be included in any other DVR. So if we schedule all the G-level cleanup procs to run before any of the C++ level cleanup procs, then the refnums a user expects are all still in play. So that might work and give us a reliable pattern. And if the user called close on any of those refnums, that's fine because that'll just pull them off of the C++ clean up list before we even start working on that list. No code races there.

matt.baker
Active Participant

I too would like this functionality (https://forums.ni.com/t5/LabVIEW/Callback-function-for-when-all-VIs-in-the-current-application/m-p/3...)

Maybe also a similar thing for by-ref classes, like a dispose and finalise method that is always executed by LabVIEW on cleanup.



Using LV2018 32 bit

Highly recommended open source screen capture software (useful for bug reports).

https://getsharex.com/
smithd
Active Participant

I don't think we can dismiss the Abort issue so easily. All it would take is one DLL that wasn't quite set up right and a user is completely hung in a VI they can't stop. They would have to kill LV and lose all unsaved work. That seems like a nasty trap to drop someone into.

This is possible already if we're talking DLLs. The natural extension to your question is, why let people use CLFNs at all since they can be written to ignore the abort button and hang forever?

 


But how about this... we unconditionally call the cleanup VIs, but after caller is aborted, we wait a suitable delay, and if the cleanup VIs aren't done, throw a dialog for "Abort cleanup VIs? [OK] [Cancel]". That seems to provide the best of both worlds -- an unconditional cleanup call and an escape valve.

This sounds more or less the way teststand does it. The big red stop button is "stop the main part" and you can run the cleanup code or choose not to, and if it takes too long it can time out. I may be mixing up a few of the details there, but I think thats all basically accurate.

The other thought that comes to mind would be having the compiler put restrictions, like no while loops or other blocking things (kind of like how subroutine VIs don't let you do x or y and inlined vis don't let you do z)

AristosQueue (NI)
NI Employee (retired)


This is possible already if we're talking DLLs. The natural extension to your question is, why let people use CLFNs at all since they can be written to ignore the abort button and hang forever?

There's a big difference (to LV R&D, at least!) between what an external system can do and what we admit to the G environment. We design G for people who aren't programmers and who aren't going to understand why they're hung. If they get hung pulling in some third-party DLL, that's not LV's fault for letting them down. But if they get hung because of code we let them write in G, that's a problem because it is LabVIEW's primary job to keep them out of such pitfalls. 

 

Any sort of automatic "timeout" system to abort the cleanup functions just leads back to the unreliable cleanup problem. It cannot be completely automatic... seems to me like it would need to be a dialog in the IDE that appears after a 1 second delay, similar to the "Quit running VIs?" dialog that you get when you hit File>>Exit while VIs are still running; that dialog would optionally be replaced in the run-time system with a user-configured timeout. Maybe an AppBuilder configured timeout could work in the run-time engine with finished code, but I don't think that's viable in the IDE with code still-in-progress.

AristosQueue (NI)
NI Employee (retired)

The idea of language restrictions -- specifically no While Loops -- is interesting, but doesn't really work because various nodes, like network communication, might need quite a while to timeout. I think that's a blind alley to try to brainstorm down, but if you want to, I'll follow you a ways into that dark. 🙂

smithd
Active Participant

I think you're right about the language restrictions. It could guide people in the right direction, but its absolutely critical that CLFNs are supported, and that throws everything out the window. So I think you have to rely on developers who use the feature to be safe.

 

Your point above is fair enough, but from that end users point of view, if they download drjd's sqlite package for example and something bad happens because they hit abort, they aren't likely to distinguish between labview and the library....with or without this feature. Without the feature, the file gets locked and windows says labview is responsible. With the feature, it provides drjdp the power resolve that issue, but if he screws up and the system hangs...well, yes, the users will still blame labview. But they were probably already doing that before.

 

So I look at it as more of a balance between giving people like drjdp the power to provide a better user experience for the whole platform (his sqlite is definitely one of the better ones, and hes the only direct postgres API I know of) vs protecting those same end users from less skilled developers, who might look at the feature and use it without testing it as well as they should.

 

I think you're right about the dialog being the better route. I was thinking there are a lot of ways that could be annoying, but the cleanup code taking too long is already kind of a corner case that adding in a dialog makes sense.

RT could be problematic given how fragile the development environment connection is -- I think its still basically the UI thread but over the network and theres a variety of modal dialogs and at least in past labview versions, various ways to end up with two modals open. I think a lot of those have been resolved though over the years.