LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Notifiers and Shared Clone Re-entrancy

Solved!
Go to solution

@PiDi

And such nuances of Notifiers made me practically avoid them in most cases (they mostly can be easily replaced by other mechanisms)... 😉

This use-case was a 'master-slave' type thing. (see post above)

 

What would you suggest as an alternative?

Nick
0 Kudos
Message 11 of 31
(1,648 Views)

@JÞB wrote:

You are sharing the data space.  So, I would expect that the 2 wait on notifications of the same notifier would each strip the notification meant for the other.  Like dequeueing the data from a queue in two places, only one instance can actually dequeue a single data.

 


Just to clarify: this is not true, two unique instances of Wait on Notification can not ever strip each others notification. But they have to be unique, as pointed in my above post.

 

 


@JÞB wrote:

 

Events, behave much differently! 1 event can trigger any and all event structures registered for the event to act... unless it's a filter event and another structure dismissed the event.  


The main difference in discussed case is that dynamic registration of events does not have any option to "see" the events before the Register for Events node executed:

notifier vs evstr.png
So we'd need to generate the event after the registration, and it's the same as sending notification after calling (and waiting in) Wait on Notifier. It's not possible to recreate the same situation as OP has using event structure - we can't generate event before registration, so it will stuck by default.

Message 12 of 31
(1,641 Views)

@paul.r wrote:

I would say its more of a shared clone nuance than a notifier nuance.


Naaah, shared clones are straightforward: assume that they will reuse the same instance at some point, which leads to the simple rule that drdjpowell stated:

One should never use shared clones with any retained state. 

 

 

(Fun fact regarding shared clones and retained state: on my CLD exam (years ago) I've accidentally used shared clone on FGV/Action Engine implementation, beacuse I've miss-clicked. I got some minus points for that, but it didn't affect functionality, as LV always called the same clone instance - it was never called in parallel.)

 

Message 13 of 31
(1,630 Views)

@PiDi wrote:

@paul.r wrote:

I would say its more of a shared clone nuance than a notifier nuance.


Naaah, shared clones are straightforward: assume that they will reuse the same instance at some point, which leads to the simple rule that drdjpowell stated:

One should never use shared clones with any retained state. 

  


Then what is the notifier nuance?

 

The issue is caused by nuances with shared clones - sometimes the same instance is used, sometimes not. Its nothing specific to notifiers, you could see the same problem with any function that uses a retained state.

Message 14 of 31
(1,620 Views)
 wrote:

@PiDi

And such nuances of Notifiers made me practically avoid them in most cases (they mostly can be easily replaced by other mechanisms)... 😉

This use-case was a 'master-slave' type thing. (see post above)

 

What would you suggest as an alternative?


My use-case was a 'master-slave' type thing. The parent called wait on notifier in its 'start' method. The 'master' - a specific child implementation would override start and send the notification before calling the parent node. It confused me somewhat why some of the classes were not executing...

I don't exactly understand what is happening in your code, could you provide some minimal code example for this?

 

 

 wrote:

@PiDi wrote:

@paul.r wrote:

I would say its more of a shared clone nuance than a notifier nuance.


Naaah, shared clones are straightforward: assume that they will reuse the same instance at some point, which leads to the simple rule that drdjpowell stated:

One should never use shared clones with any retained state. 

  


Then what is the notifier nuance?

 

The issue is caused by nuances with shared clones - sometimes the same instance is used, sometimes not. Its nothing specific to notifiers, you could see the same problem with any function that uses a retained state.


Notifiers actually have two retained states: one is in the reference (notifier history is there), second one is in the Wait on Notification node (as it "remembers" that it already read the notification - hence our problem here). You have to keep track on both if you want to analyze if certain Wait on Notification node on the block diagram will complete or not. So it's highly dependent on the context that this Wait on Notification is put. I'm not sure if there is anything else in native LabVIEW that acts that way. Queue retains its state in the reference only (queue VIs are stateless). File operations retain their state in the reference only. For example: if you call Write, it moves cursor to the end write position "in the reference", not in this unique Write instance. So every subsequent call to Write instance, be it the same or other instance, will start at the same cursor position. On the other hand, there are VIs that retain their state in the instances (like Point By Point signal processing pallete), but they do not have any additional reference wire. Notifiers have both, which can bite you.

 

In addition, I can live without notifiers, but I can't live without shared clones 😉 One reason is the same as niNickC has - reentrancy to dynamic dispatch VIs can only be archieved using shared clones. Second reason is obviously optimization.

 

(And maybe that's just the irrational, personal thing, that I don't like Notifiers, the same way that I don't like Shared Variables... No, wait, Shared Variables hate is actually normal 😄 ).

 

Message 15 of 31
(1,610 Views)

@PiDi wrote: No, wait, Shared Variables hate is actually normal 😄 ).

It is actually the Network Published Shared Variables (NPSVs) that I have "issues" with.  And by "issues", I mean a burning hatred only matched by the fury of a woman scorned.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 16 of 31
(1,601 Views)

@crossrulz wrote:

@PiDi wrote: No, wait, Shared Variables hate is actually normal 😄 ).

It is actually the Network Published Shared Variables (NPSVs) that I have "issues" with.  And by "issues", I mean a burning hatred only matched by the fury of a woman scorned.


Yes, yes, those little bugg...y things 😄

0 Kudos
Message 17 of 31
(1,596 Views)

Thanks everyone for your input.

 


@PiDi

I don't exactly understand what is happening in your code, could you provide some minimal code example for this?


Check the attached project for an idea of the kind of functionality I was after.

Nick
0 Kudos
Message 18 of 31
(1,589 Views)

I'm still not sure how do you want to use it - you didn't provide any usage example, and I can't put the puzzles together somehow (maybe I'm just tired) 🙂

 

Anyway, I'll try to make a bit more general approach to this and post some notifications-without-Notifiers patterns below. Please note that those are patterns, not examples, templates or ready-made solutions. The actual code using those patterns migh look very different from the one below, but the mechanisms behind that code may be just exactly the same (invalidating references, using single element queues). All of this mainly in the context of avoiding Notifiers in shared clones.

notification_patterns.png

 

In your specific case, if I got your intention right, you want to synchronize the start of some hardware. So you might want to try the first pattern - instead of Sending Notification, you might want to release the Notifier and check for invalidated reference in your Start VIs.

 

Message 19 of 31
(1,562 Views)

Awesome effort - Thank you for your super detailed reply.

 

 

The lack of error handling in the first one is probably a deal breaker in many applications... Furthermore, you don't really want to be polling in a synchronisation use-case. (of course you could just use 'wait on notifier' instead of check for valid reference)

 

Your separate use-case for the third one aside, the second and third ones are kind of the same really: one polls get queue status and one uses preview queue element. The problem I have with these is that when to flush the queue can become problematic, especially if you want multiple iterations of the secondary loops - you can't flush the Queue until every loop has reported done but faster loops might spin through a few times before this happens. Now you are left adding additional logic, like some kind of counter... but this requires a saved state surely and we are back to square one.

 

I get the feeling that my takeaway (and opinion!) is becoming that the problem still lies with the nature of pre-allocated clones! This leads down the rabbit hole of pre-allocated clones for dynamic dispatch VIs... 

Nick
0 Kudos
Message 20 of 31
(1,466 Views)