Jump to content

The property node design pattern where you edit a parameter by selecting which one is "active" is a horrible design


Recommended Posts

17 minutes ago, JCAndersen said:

Well you have a clear race condition here when setting the "ActPlot" property in two parallel running loops, so I do not see how the behavior you describe is a surprise. It is working completely as one should expect.

I think that is the point he is trying to make though (based on the title of the thread); that LabVIEW should let us specify which plot we are working on when setting a property without it being overruled by what is done elsewhere as long as that is not actually on the same plot. If e.g. you have one location where you want to set the property of plot 2 and you also have some code in parallel working on a a property of plot 4 they should be able to declare/access the separate plots *without the risk of a race condition*.

I agree with @infinitenothing, it is a bad design (I have not checked if anyone has already asked for a change of that in the idea exchange though. It would be a good idea to post there.)

  • Like 1
Link to comment

I don't see how should Labview know which plot you intend to work on and what different method there could be. Sure, the above example should be easy to figure out but it's easy to come up with funkier situations. Maybe each plot should have its own reference, but I don't see that a superior solution. Or maybe choosing the active plot should be forced (invoke node instead of property node)? That's not too sympathetic either.

This pattern is far better than having an array of sub-property clusters and to manipulate those arrays. Though I agree that all these types of properties should have array version too, like graph cursors and annotations for example.

I often do ugly hacks with graphs and this problem never really got me. The code in the original post (I don't understand as it has some new blocks I don't know) seems like the model-view-controller is not separated enough.

Edited by Lipko
Link to comment

Does a Property Node, with multiple Properties set, execute as a single action, without a parallel Property Node executing in the middle?   If so, then resetting the Active Plot in the second Property Node in the bottom loop would prevent any race condition.

Link to comment
2 hours ago, Lipko said:

I don't see how should Labview know which plot you intend to work on and what different method there could be. Sure, the above example should be easy to figure out but it's easy to come up with funkier situations. Maybe each plot should have its own reference, but I don't see that a superior solution. Or maybe choosing the active plot should be forced (invoke node instead of property node)? That's not too sympathetic either.

This pattern is far better than having an array of sub-property clusters and to manipulate those arrays. Though I agree that all these types of properties should have array version too, like graph cursors and annotations for example.

I often do ugly hacks with graphs and this problem never really got me. The code in the original post (I don't understand as it has some new blocks I don't know) seems like the model-view-controller is not separated enough.

I think either of those ideas would be superior. The graph should have a plots property that returns an array of plot references. We see this architecture with things like tabs having an array of page references. An invoke node that didn't force you to do a write when you only want to do a read would also avoid this problem.

 

38 minutes ago, drjdpowell said:

Does a Property Node, with multiple Properties set, execute as a single action, without a parallel Property Node executing in the middle?   If so, then resetting the Active Plot in the second Property Node in the bottom loop would prevent any race condition.

Even if it was a single action, is there a promise to maintain that in future versions? I solved this issue by wrapping the graph reference in a DVR.

Edited by infinitenothing
Link to comment
2 hours ago, drjdpowell said:

Does a Property Node, with multiple Properties set, execute as a single action, without a parallel Property Node executing in the middle?   If so, then resetting the Active Plot in the second Property Node in the bottom loop would prevent any race condition.

I would really like to know the answer to this question.  I would expect the answer to be "yes" since property nodes all run in the UI thread

Link to comment
24 minutes ago, bjustice said:

I would really like to know the answer to this question.  I would expect the answer to be "yes" since property nodes all run in the UI thread

I remember it's stated somewhere. And if  wasn't that way, that would be a horrible pattern.

Link to comment
1 hour ago, infinitenothing said:

I think either of those ideas would be superior. The graph should have a plots property that returns an array of plot references. We see this architecture with things like tabs having an array of page references. An invoke node that didn't force you to do a write when you only want to do a read would also avoid this problem.

Yup, I mentioned the reference thing too. With reference array you of course have to do explicit array indexing and wire the reference all around, I don't see much improvment. It's just personal preference 

Link to comment
  • 2 weeks later...
On 11/10/2022 at 11:26 AM, Lipko said:

Yup, I mentioned the reference thing too. With reference array you of course have to do explicit array indexing and wire the reference all around, I don't see much improvment. It's just personal preference 

The advantage is that indexing an array of refnums does not change the internal semi-hidden active plot state of the control.

Link to comment
Quote

Does a Property Node, with multiple Properties set, execute as a single action, without a parallel Property Node executing in the middle?   If so, then resetting the Active Plot in the second Property Node in the bottom loop would prevent any race condition.

if you encapsulate the actions in a single subVI (non reentrant) then you can avoid any race condition.   The answer to above question is a property nodes that are stacked each run in series .  There's no difference besides Block-diagram horizontal saving  from when you individually place them.  You can even right-click and choose ignore errors inside Node, which I would not recommend.

Plot.Property change.viimage.png.c23045f2998b315ae4486ec370f747bb.png

Link to comment

Totally tangentially... I had an interesting bug once, and I eventually tracked it down to stacked property nodes.

Something which is probably expected when you think about it, but not obvious at first is that if one of the actions of a property node does give an error then the following property nodes do not execute. I guess this is related to the comment posted by @sam above regarding ignoring errors.

I never expected a property node could fail if the reference was valid, but there are certain conditions where it can happen. I forget what caused it though.

Link to comment
1 hour ago, sam said:

There's no difference besides Block-diagram horizontal saving  from when you individually place them.  You can even right-click and choose ignore errors inside Node, which I would not recommend.

Actually, BOTH behaviours with or without "ignore errors inside node" set are different from error-chaining the individual subVIs (which is how I would argue stacked Property Node should behave).

  • Like 1
Link to comment
On 11/10/2022 at 5:29 PM, infinitenothing said:

Even if it was a single action, is there a promise to maintain that in future versions? I solved this issue by wrapping the graph reference in a DVR.

I generally solve it by not forking the reference wire and not acting on it in parallel.  It's all in the UI thread anyway so there is no performance advantage to parallel execution.

Link to comment
20 hours ago, drjdpowell said:

I diagram I made in another conversation, illustrating the issue:

1378337125_2021-02-2511_26_35-Untitled1BlockDiagramonUntitledProject1_MyComputer_.png.57172da783c0b191316ee37e5d818733.png

I don't quite understand these. Do youn mean the problem is that the a read function duesn't use the error input in a sophisticated way other than "if error then return that error and do nothing" or "do the task regardless of error and merge error with the input error"? The latter is bad, but what's the problem with the previous in a general case?

What do you mean by the "I want this" row? On the caller VI level the insides of the read functions could be anything, including the two bad examples below that row.

Sorry for OFFing, error handling is a very interesting topic and so far all error handling I've seen was "chain every crap which has error terminals even ones that will never produce error into one God error snake" from even people hired as LV architects.

Link to comment
3 hours ago, Lipko said:

On the caller VI level the insides of the read functions could be anything, including the two bad examples below that row.

Exactly.  The function can do the approprioate thing, based on there being an upstream error.  Ususally that is doing nothing, sometimes it is doing what it would have even if no error, and occasionaly it is something different.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.