LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

LVOOP with DVR - Best Practices and Caveats

Hi dear community, I would like to ask for advices about LVOOP.

 

I have an application where I am using a FGV to contain a DVR, it is a large array. This buffer can be filled with data of many sources (Database and several filetypes) so I am using a LVOOP to read the data and currently the DVR is an input of a method to transfer the data. I have several asynchronous VIs where I use the DVR.

 

Now I want to integrate the buffer into my class, because the FVG implies that I cannot instantiate more than 1 object producing a Singleton behavior for my class. I have read the information available, specially these topics:

 

https://lavag.org/topic/16510-dvrs-within-classes/

https://lavag.org/topic/19248-dvrs-for-accessing-class-private-data/

 

But I saw divided opinions. In some moment I thought about including a typedef DVR inside the private data of my class and of this way I can keep the dynamic dispatch.

 

Other better way using the same approach could be create a class to handle DVR operation and include this class inside the parent class when I retrieve the data, this class would be by REF.

 

A third way in my head is to include the array in private data and convert my classes to retrieve data in by REF.

But I think I will need building wrappers to use dynamic dispatch.

 

But like I said I saw different opinions about the approaches, and that is the reason to consult the topic. I know that probably I am missing something and could have a better way.

 

I hope that this topic can be used to share best practices and advices about the usage of LVOOP and DVR. 

 

Thanks in advance for the attention.

 

0 Kudos
Message 1 of 36
(6,142 Views)

Best practice (IMHO): Avoid DVRs at all costs.

 

They are a pain, as they get disposed when the code stops running. So you can not debug sub VIs.

 

You talk a lot about why\why not to use DVRs. You should tell us what you want instead. Better jet: show us the design. OO Programming should be preceded by OO Analysis and OO Design, at least for best results. 

 

If you want singleton behavior, I'd consider a private global in a class. It won't avoid race conditions, but at least the data is still there when you stop your code. It's all very dependent on the situation, so we need to know about that. You can also wrap the FGV in the class, but do make it private (or at least protected).

 

For me, a DVR in a class is a "by reference" pattern. You shouldn't use patterns (like an actor pattern Smiley Wink) as a solution to everything. Use when needed...

Message 2 of 36
(6,088 Views)

I'm not sure what you want or need exactly, but if you have identified that you need a by-ref solution, then I suggest you check out G#. It adds reference-based class support to LabVIEW, and it has a powerful debugger (to inspect the internal DVRs). G# also supports standard LabVIEW-native-classes.

 

If I imagine what you are after, I can see similarities with one project where we had an application that sampled lots of data on many channels, these were stored to tdms-files, but some parts (a buffer for the most recent time) were kept in DVRs (G#-classes) and sent through computational "filters" or analyzing algorithms (and that result was also kept in DVRs), and then the GUI could subscribe to those feeds. It works like a charm and with very high performance.

 

G# is found in VIPM

Certified LabVIEW Architect
Message 3 of 36
(6,071 Views)

wiebe@CARYA wrote:

Best practice (IMHO): Avoid DVRs at all costs.

 

They are a pain, as they get disposed when the code stops running. So you can not debug sub VIs.

 

You talk a lot about why\why not to use DVRs. You should tell us what you want instead. Better jet: show us the design. OO Programming should be preceded by OO Analysis and OO Design, at least for best results. 

 

If you want singleton behavior, I'd consider a private global in a class. It won't avoid race conditions, but at least the data is still there when you stop your code. It's all very dependent on the situation, so we need to know about that. You can also wrap the FGV in the class, but do make it private (or at least protected).

 

For me, a DVR in a class is a "by reference" pattern. You shouldn't use patterns (like an actor pattern Smiley Wink) as a solution to everything. Use when needed...


I think this is a bit of an extreme. DVRs are a valuable tool your the toolbox. They can be abused like any other thing can but they are also very useful. We use them often. For me the decision to using a by reference to a by value class comes down to what exactly am I representing and whether the wire might get branched. If I am representing a physical item in the real world I prefer to use DVRs if I need to maintain state information about that item. The last thing I want is to branch a wire somewhere and all of a sudden my nuclear reactor is both on and off at the same time because the branch effectively cloned my reactor and now I have two copies of it.



Mark Yedinak
Certified LabVIEW Architect
LabVIEW Champion

"Does anyone know where the love of God goes when the waves turn the minutes to hours?"
Wreck of the Edmund Fitzgerald - Gordon Lightfoot
Message 4 of 36
(6,047 Views)

@Mark_Yedinak wrote:

wiebe@CARYA wrote:

Best practice (IMHO): Avoid DVRs at all costs.

 

They are a pain, as they get disposed when the code stops running. So you can not debug sub VIs.

 

You talk a lot about why\why not to use DVRs. You should tell us what you want instead. Better jet: show us the design. OO Programming should be preceded by OO Analysis and OO Design, at least for best results. 

 

If you want singleton behavior, I'd consider a private global in a class. It won't avoid race conditions, but at least the data is still there when you stop your code. It's all very dependent on the situation, so we need to know about that. You can also wrap the FGV in the class, but do make it private (or at least protected).

 

For me, a DVR in a class is a "by reference" pattern. You shouldn't use patterns (like an actor pattern Smiley Wink) as a solution to everything. Use when needed...


I think this is a bit of an extreme. DVRs are a valuable tool your the toolbox. They can be abused like any other thing can but they are also very useful. We use them often. For me the decision to using a by reference to a by value class comes down to what exactly am I representing and whether the wire might get branched. If I am representing a physical item in the real world I prefer to use DVRs if I need to maintain state information about that item. The last thing I want is to branch a wire somewhere and all of a sudden my nuclear reactor is both on and off at the same time because the branch effectively cloned my reactor and now I have two copies of it.


Sure, if you don't like debugging... And love those in placement structures.. DVRs are great.

 

How about OpenGDS by reference class if you want a by reference class? Last I heard, they are persistence, and you get by reference behavior for free. Will check that soon...

0 Kudos
Message 5 of 36
(6,044 Views)

How about OpenGDS by reference class if you want a by reference class? Last I heard, they are persistence, and you get by reference behavior for free. Will check that soon...


AFAIK (Open)GDS does not register the objects, thus cannot be debugged. That could have changed though, it was some years ago I checked. A core concept of G# is that it registers the objects and thus they can be debugged. It even supports remote debugging (used for RT-targets e.g.), and the debugging events are logged and even shows up in DETT (desktop execution trace toolkit). It also has a an active debug mode to debug classes without the need to write an application to create objects. G# objects also has a method to create objects in an external process (separate thread), if you want them to be persistent. Very convenient for dependency injection.

Certified LabVIEW Architect
Message 6 of 36
(6,010 Views)

Hi to everyone, thanks for the responses. I am agree that if I provide code is easy for all to give me feedback.

 

I am uploading a quick demo app about I am working.  The complete idea for the app is described below, if you need more information please tell me.

 

@wiebe: "You talk a lot about why\why not to use DVRs. You should tell us what you want instead. ". 

I am not against to use LVOOP by reference, but where I work there is not an architect and I have doubt about what is the best option. Until now I have only worked with by value approach and dynamic dispatch is great so I want to keep this functionality if it is possible. I hope you can give me tips to solve the problem of the best way.

 

@thols: I have not used G#, I am reviewing the product, thanks for the info.

 

And yes, the purpose of the application is similar that you described, it is an analysis and visualization tools for data, these can come of several sources, mostly different filetypes hence currently I am using a DVR buffer to avoid copies of data, in the real application, there is VI to launch several asynchronous modules and there is a Main VI where the async modules are seen with a subpanel. In the Main VI the user will select the data source and the data scanning will be performed there, after that I am thinking about to use an user event to tell asyn modules that data is ready, some modules will do operations with the data immediately after it is available while others are under request (User interaction). 

 

@Mark_Yedinak: I have read some of your posts and I saw that you use a lot LVOOP approach, so I would like to ask for an advice about the way you face this scenario.

 

Thanks in advance for the help.

 

0 Kudos
Message 7 of 36
(5,994 Views)

Please attach an actual zip file, not a .7z file.  Not everyone has bothered to download 7zip when Windows has built-in support for classic .zip files.

Message 8 of 36
(5,982 Views)

Done, thanks RavensFan I did not realize that it was 7 zip.

0 Kudos
Message 9 of 36
(5,971 Views)

@AYanez wrote:

@wiebe: "You talk a lot about why\why not to use DVRs. You should tell us what you want instead. ". 

I am not against to use LVOOP by reference, but where I work there is not an architect and I have doubt about what is the best option. Until now I have only worked with by value approach and dynamic dispatch is great so I want to keep this functionality if it is possible. I hope you can give me tips to solve the problem of the best way.


Still not sure what the problem to solve is. Haven't looked at the code yet.

 

I have 306 classes in my current project, and none is by reference. Actually 1 has a DVR. I can switch it to by wire, but somehow it's less efficient for LabVIEW. Pretty sure that there are no copies and such. At some point I will refactor that one out (switch to the by wire child and delete the by reference).

 

It is possible to avoid by reference classes altogether.

 

It is probably also possible to only use by reference classes.

 

One thing to realize is the problem by reference classes try to solve, can actually cause problems as well. Problems by wire classes don't have (and why I use them).

 

One good example is the file reference library (not a class, but by reference non the less). The by reference is very convenient. You can read and write anywhere. But if there's a dialog that changes settings, you can't write them directly to the reference, because you want the user to press OK first. So now you have to start synchronizing things, because of the by reference construction. By wire doesn't have this problem, but the distribution is a problem. So once the dialog changed it's (copy of) settings, you'll need an event\queue\etc. (even a global would work) to communicate to the parallel threads using the data.

 

I prefer to stick with one paradigm. I know others who always use by reference.

 

I prefer by wire, because all normal data in LabVIEW is by wire. It's closer to the data flow paradigm.

0 Kudos
Message 10 of 36
(5,953 Views)