11-01-2018 06:39 AM
@PiDi wrote:
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).
IIRC, this is partially correct. A notifier itself (the object in memory the notifier reference points to) only has a timestamp as "state". This is the timestamp of the last element written to the notifier. It contains no history.
The Wait on Notifier node, however, remembers the timestamp of the last notificationit has read. If you call a sub-VI twice with two different notifier refnums, the node will only compare the timestamps (it doesn't even notice that you have wired a DIFFERENT notifier to the node). If the timestamp of the second Notifier is older or equal to the first, the node will NOT read the notifier, waiting instead for the next value (even though it has actually never read the existing one). There is an optional "Wait on Notification with Notifier History" . This actually stores the timestamps for EACH unique Notifier reference used with the node. While this might seem kind of useful, if your pool of notifiers isn't finite then this is going to end up as a memory leak essentially as the store of timestamps will continually increase.
The first line of the help for this function states:
"Waits until a notifier receives a message. This function tracks the most recent message and timestamp for each individual notifier when you use this function repeatedly with different notifiers."
When using shared clones, you will essentially be calling the same Notifier node with different notifiers (pre-allocated clones should NOT have this problem). I ran into exactly this problem a while back. Took me some headscratching and discussions to actually find out what's going on in the background.
11-01-2018 07:17 AM
Intaris, are you claiming this is a 'bug' with pre-allocated clones?
11-01-2018 07:29 AM - edited 11-01-2018 07:30 AM
What do you refer to with "this" exactly?
I'm certainly not claiming that "this" is a bug because I don't know what "this" is. But one speicfic use case which I encountered showed problems with shared clones which disappeared with pre-allocated clones. Depending how the notifier references are being handed aorund, it could well be that the same problems can occur with preallocated clones. I've not analysed this enough to make any kind of informed claim one way or another.
What I can imagine (unproven) is that if you have N clones, each with an internal loop witha different unique notifier being passed to it (at initialisation), then there may be differences inbehaviour between shared and pre-allocated. In the shared case, there is not a specific 1:1 relationship between sub-VI and notifier instance whereas with the pre-allocated clones there is.
11-01-2018 07:35 AM
Ah sorry I wasn't more specific.
I was referring to the behaviour described in my first post: with a set of shared clones only a select number 'receive' a notification.
Do you believe shared and pre-allocated should behave exactly the same? (apart from performance: speed and memory)
11-01-2018 07:51 AM
No, with notifiers, shared clones and pre-allocated clones will not behave the same due to the reasons I have outlined above.
The wait on notification node (not the notifier reference) has a state information. The interaction between state and notifier reference (whether to notify or not) will be different for shared clones (where notifier and state can be muddled up) than for pre-allocated clones (where notifier and state cannot be muddled up).
11-01-2018 09:32 AM
The issue that Intaris described very clearly is the same one I half-remembered in my earlier msg. The "Wait On Notification" primitive doesn't do well with a use case where it might be waiting on different Notifiers from one wait to the next. That would be a failure scenario that's mostly about the behavior of "Wait on Notification".
However in your original posting (msg #1), you only ever create 1 Notifier, so there, you're facing a different issue -- the one pointed out already by several other posters. With shared clones, N block diagram instances can correspond to any number 1 to N of actual unique data spaces at any given time. Further, that correspondence can change over time as the pool of available data spaces can grow to accomodate perceived need.
The best simple advice came from drjdpowell back in msg #6. Don't use shared clones for vi's that retain state between calls.
-Kevin P
11-01-2018 09:48 AM
Yes, the problems we are trying to clarify are all based on the same thing.
Shared clones and stateful VIs don't play well together.
Having a "Wait on Notification" node on your BD makes your sub-VI stateful.
Don't use shared clones with "Wait on Notification" without taking steps to make sure you can guarantee avoiding the pitfalls we have mentioned here.
11-01-2018 10:03 AM
@Kevin_Price wrote:
However in your original posting (msg #1), you only ever create 1 Notifier, so there, you're facing a different issue -- the one pointed out already by several other posters.
It took me a while to get what Kevin is saying here.
Essentially, your problem is the reverse of what I am saying, but has its origins in exactly the same source. Just as you can't predict whether a given shared clone callsite will always get the same internal state, the reverse is also true. You can't guarantee that different shared clone callsites don't actually get the SAME state. This is what is apparently happening in your code where a single shared clone is a actually processing TWO "wait on notifier". Since the timestamp on the notifier reference has not changed since the first read, the same node "remembers" that it has already returned the data in the notifier and refuses to pass the data on in the second instance.
The following is my understanding of the Timestamps and "ignore previous" with Notifiers. It may be incorrect - read with a sceptical mindset.....
There may also be a misunderstanding how the "ignore previous" option works. There are three timestamps to take care of here. Timestamp of the data in the notifier data itself (A) and the timestamp of the last succesful Read on the "Wait on Notification" node (B). The time at which the node starts executing (the current "wait" - against which the timeout is measured) is (C). Note that C is guaranteed not older than B while waiting.
If A is older or equal to B, then the data will not be regarded as valid, irrespective of C or the setting for "ignore previous".
If A is newer than B but older than C then the data is returned if "ignore previous" is FALSE but not returned if it is "TRUE.
If A is newer than B and newer than C, the notification has arrived AFTER we have started waiting and the data is returned irrespective of the setting for "ignore previous".
Note that A can never be newer than C but older than B when waiting.
That's my understanding at least. It's a bit complicated.
11-02-2018 09:38 AM
Hmmm, my working understanding differs from yours on one point (maybe. Could be we have different unstated assumptions.) Readers: carefully read the spoiler above in msg #28 for context.
If A is older or equal to B, then the data will not be regarded as valid, irrespective of C or the setting for "ignore previous".
My thought: If A is older or equal to B, the data will be returned (probably *again*) at the end of the timeout period if "ignore previous" is False. If "ignore previous" is True, data is not eligible to be returned. (The successful previous wait that makes B newer than A probably already returned the A data last call.)
-Kevin P
11-05-2018 07:53 PM
@niNickC wrote:
@drjdpowell
I came across this in a dynamically dispatched VI which cannot use the pre-alloc type...
Yeah, that one surprised me today! I would actually like to know why I cannot preallocate a dataspace for a dynamically dispatched vi. Like, if I wanted to have state information for a several specific HAL resources that want to be instantiated as a test object? But, I'm not the SE guy!