LabVIEW Idea Exchange

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

Persistent Data Value Reference (DVR)

Status: New

I have long defended NI's decision to bind the lifespan of DVRs to their creator VI but, with the addition of malleability (totally awesome) and the fix in LV 2020 that allows "New Data Value Reference" to be called directly in an inlined VI (thanks, AQ), the ephemeral auto-cleanup behavior of DVRs is now a big blocker to a reference-based strictly-typed API.

 

I want to open a strictly-typed and malleable reference and keep that reference open until I choose to close it, regardless of whether the opener leaves memory. Without malleability, I could delegate the DVR creation to another thread/VI and get the persistent reference back by callback but I can't have the home-baked persistence and the malleabilty.

Please add a persistence/auto-cleanup flag to New Data Value Reference so I that reference can persist if I want it to. (I need both the persistence and the malleability to write some really cool code.)

Persistent_DVR_idea.png

Here's an old request for this feature that was declined, but things have changed a lot since then: https://forums.ni.com/t5/LabVIEW-Idea-Exchange/Persistent-DVR-s/idc-p/2856348#M27799 

37 Comments
wiebe@CARYA
Knight of NI

Yes, I think I like it 😁.

drjdpowell
Trusted Enthusiast

Would a "static" DVR work for your use cases?  One where a particular call site always returns the same DVR.  That would match how a lot of other LabVIEW things works (controls, initialized shift registers), and avoids the potential for memory leaks with dynamically-created things that are never automatically cleaned up.

EthanStern
Member

Thanks for the idea, @drjdpowell. I don't think that would yield a solution I'm happy with.

 

I'm writing a functional concurrency add-on that allows dynamic creation of mutable global refs (like Clojure). I want to construct/open these global data references in any possible combination on any possible type. For the synchronous modify use case (i.e. "atom"), I'm tantalizingly close with the improvements to malleability.

 

I'll think more on your suggestion. I would need one constructor (call site) per global reference. I don't love it because it smells like functional globals, creates more files on disk, and requires scripting for any user besides me to prepare these references.

 

Here's the idea driving my request (obviously this call doesn't care about persistent DVRs but, in a real application, I'd open these references during launch and provide access to the mutable state to actors/loops/VIs by ref wire).

 

EthanStern_0-1622906554992.png

 

drjdpowell
Trusted Enthusiast

I must not have communicated it well, as my idea doesn't involve any extra VIs or scripting of any kind.  It would be slightly simpler than your example as there would no "Close" needed (closing static references is a no-op).

drjdpowell
Trusted Enthusiast

I think a static VI reference is the best example of what I mean, though I don't know if you have used them.  

raphschru
Active Participant

I hope I understood your problem correctly.

Here is the workaround I would use (just replace the content of "Create DVR External" by how you would do to actually create a DVR in another process):

 

raphschru_2-1623008373119.png

 

There might be a slight overhead due to the variant conversions, but you have external DVR creation AND malleability.

wiebe@CARYA
Knight of NI

>Would a "static" DVR work for your use cases?  One where a particular call site always returns the same DVR. 

 

My main problems with DVRs are they stop existing when the top level data space VI is stopped.

 

If 'static' covers that, then it would be helpful for some use cases.

 

This would especially be useful if the DVR is static from the start, I mean without the need to initialize it. It would simply be there, ready to use.

 

There are still cases where you want by wire references that persist.

drjdpowell
Trusted Enthusiast

>This would especially be useful if the DVR is static from the start, I mean without the need to initialize it. It would simply be there, ready to use.

 

Yes, static things work that way.  A Static Reference to a preallocate-clone-reentrant subVI, for example, returns the pre-existing reference to a pre-existing clone.  Static resources are created on load of the owning VI, rather than at run time as dynamic resources are.

 

I'm thinking this won't satisfy OP's use case, but it would allow probing the DVR in an idle VI.

drjdpowell
Trusted Enthusiast

>I'd open these references during launch and provide access to the mutable state to actors/loops/VIs by ref wire

 

Ethan, I don't understand the problem if you do this, as your launch code will then "own" the references, and all you have to do is make the top-level VI containing launch code remain active for the entire time of the application (and I would argue it is the natural thing to do would be to have a top-level actor that starts everything and shuts-down everything).

EthanStern
Member

@drjdpowell

 

> "all you have to do is make the top-level VI containing launch code remain active for the entire time of the application"

 

I agree that this is neither hard nor (usually) bad. I have, however, known plenty of clever LV developers who DESPISE this requirement for managing reference lifespan. I also want to support the use case where application scope (here I mean: what is getting launched...and when) is more dynamic than a top-level launcher can reasonably know. Certainly not my typical programming case, but a valid one, I think.

 

Regarding "static" DVR, I might be missing how a programmer would use this feature. Would they create one 'static DVR' per variable (like VI, global, etc.)? Or would there be a malleable primitive (a new static DVR) that could be dropped on a diagram and malleably adapt to any input type? I was thinking the former with my prior comments and I don't want to define these DVRs anywhere but on a block diagram in the syntax of G.

 

@raphschru Thanks! That's an idea I bounced around but didn't implement because I specifically wanted strict types everywhere and no run-time conversions/allocations. Seeing it on the screen makes me wonder how it would benchmark against the non-variant approach I'm using now. With in-place variant-to-data conversion, it might be darn quick, and that's probably good enough.

 

I still want an option to avoid workarounds, though!