Jump to content

Darren's Occasional Nugget 08/07/2023


Recommended Posts

I don't post on the dark-side but I thought Darren's Occasional Nugget 08/07/2023 was a nugget well worth commenting on over here.

I have used this behaviour for a very, very long time. Every time I use it, I always have to convince myself that NI will not "fix the bug" like they did with events and tunnels. I always thought it was an anomaly when compared to the other  API's-but a very welcome one which, as Darren rightly says, "this behavior makes event programming more straightforward than other APIs".

Darren's example may seem a bit contrived and convoluted so I would like to add a real-world, concrete, practical example which would not work correctly without this behaviour.

image.png.f97d25c115c28ec9a67b9370f0a7e81e.png

The example (which is one of many that use this behaviour) relies on the "On Status" event being fired after the the event reference is destroyed in the "Close" function. Actually it is fired twice. Once for "Closing" and once for "Closed".

image.png.744b98c849e323d4d779eb63892e851b.png

If the event on the structure's queue was not retained and actioned after destruction, then the "Closing" and "Closed" events may never reach the loop - it may not terminate. There would be a high probability that a "Closed" status may not be received and it would be a race between the event structure executing and the "Close". A specific "shutdown" event would have to be added and managed - greatly increasing the diagram complexity. (this one reason why "Tunnels" and "Actor Framework" are so complex).

But it gets better. Regardless of the Destroy primitives, all data and status' from the "Get" function, in the executed order, are also maintained independent of the speed of execution of the event structure. This means that when in debugging mode we can see all the events' data and execution even after the Destroy function has been executed in the "Close". As Darren has pointed out, a queue reference would not behave in this way and report "Refnum No Longer Valid" making debugging a much more difficult task.

 

Edited by ShaunR
  • Like 1
Link to comment

It's not a bug and there is nothing that could be fixed here.

The user event is not the same as the event registration!

The user event is an event object that manages events in an internal FIFO queue to pass the event over to the event wait node AND/OR to any number of attached event registration handlers.

When it is registered with the register node, a new independent object is created that contains its own event queue and that event registration is then connected to the event with an event registration handler that simply passes the event to this queue in addition to the internal event queue. Once the event is gone, all the events that are stored in the internal queue of the event are of course gone, but the events also were passed to the queue of every attached event registration queue. That queue remains valid until the event registration refnum is closed itself.

The event registration is special as it can attach to any object that can expose an event interface, such as ActiveX objects, or .Net classes too (if they have defined events). Also LabVIEW front panel objects actually can provide an event interface and their refnum can be connected to a Register Event node.

 

 

Edited by Rolf Kalbermatter
Link to comment
57 minutes ago, Rolf Kalbermatter said:

It's not a bug and there is nothing that could be fixed here.

Oh I don't know. They could delete the registration queues of any registration that referenced the event that was destroyed - they have to delete the registration queue at some point, right?. Luckily, that hierarchy isn't implemented and hopefully it would be too tiresome to implement.

57 minutes ago, Rolf Kalbermatter said:

The event registration is special

I love LabVIEW events. I rate them alongside Dataflow, sliced bread and putting men on the moon. :D

Edited by ShaunR
Link to comment
2 hours ago, ShaunR said:

Oh I don't know. They could delete the registration queues of any registration that referenced the event that was destroyed - they have to delete the registration queue at some point, right?. Luckily, that hierarchy isn't implemented and hopefully it would be too tiresome to implement.

That would make little sense. That event queue is owned by the registration refnum, and the registration refnum registers simply a callback in the event object. The event is able to have multiple callbacks registered as it "queues" them up internally. That's what makes it possible to have multiple registration refnums connected to the same event object.

That makes resource management fairly easy, avoids polling and objects owning other objects. Once the event goes away it simply will stop posting any events to the registered callback (it forgets about the callback since it is non-existent). The event queue in the event registration object still exists until that event registration object itself is destroyed. And if you close the event registration refnum earlier it simply deregisters itself from the event.

Edited by Rolf Kalbermatter
Link to comment
14 hours ago, Rolf Kalbermatter said:

That event queue is owned by the registration refnum

It is indeed. But it doesn't have to be They could have decided it should behave like Queue's and an Event Reg merely creates a reference to the internal queue. IMO, Darren's nugget is a side effect of an implementation peculiarity (which you have explained in exquisite detail) rather than a philosophical design - a peculiarity I hope never changes :) .

Link to comment
59 minutes ago, ShaunR said:

It is indeed. But it doesn't have to be They could have decided it should behave like Queue's and an Event Reg merely creates a reference to the internal queue. IMO, Darren's nugget is a side effect of an implementation peculiarity (which you have explained in exquisite detail) rather than a philosophical design - a peculiarity I hope never changes :) .

That would be a management nightmare. There would be no possibility to handle more than one event registration to subscribe to the same even generator without very involved buffer management. By placing the event queue into the event registration object it is fairly simple.

1) Hey here is my event queue, post any event you get to it.

2) I only have to check that queue to see if there is any event to handle. Not some other queue that might or not might have events present that I already processed but need to remain in it because not all event registrations have yet gotten to read that event.

There is a relatively cheap check needed in the event generator to see if the event registration queue is still valid before trying to post a new event to it but that’s much easier than turning the single.queue into a pseudo random access buffer for use with multiple registrations.

Similarly the event registration needs to check that the event generator is still valid when trying to deregister itself from it on its own destruction but that’s again a fairly simple Is Not an Object/Refnum check.

Link to comment
57 minutes ago, Rolf Kalbermatter said:

That would be a management nightmare. There would be no possibility to handle more than one event registration to subscribe to the same even generator without very involved buffer management. By placing the event queue into the event registration object it is fairly simple.

1) Hey here is my event queue, post any event you get to it.

2) I only have to check that queue to see if there is any event to handle. Not some other queue that might or not might have events present that I already processed but need to remain in it because not all event registrations have yet gotten to read that event.

There is a relatively cheap check needed in the event generator to see if the event registration queue is still valid before trying to post a new event to it but that’s much easier than turning the single.queue into a pseudo random access buffer for use with multiple registrations.

Similarly the event registration needs to check that the event generator is still valid when trying to deregister itself from it on its own destruction but that’s again a fairly simple Is Not an Object/Refnum check.

I'm not really sure what we are arguing about here. I like events as they are (and have said so) and only said that I hope they don't change it the more general view of the LabVIEW API's. If you want me to seethe with indignation about implementations, then talk to me about reading an end of file as an error :D

Link to comment

I get where Shaun is coming from here.  There are some behaviors in LabVIEW that either weren't well defined, or up for interpretation on how it should work.  Then a new fix would come to LabVIEW where all of the sudden those corner cases weren't the same.  Events are one of those things I've also thought might change, but I'm glad to hear that likely isn't the case.  I remember a presentation by Jack Dunaway years ago at NI Week I think that talked about some of the event behaviors, and how it has changed in some releases.  This was in the 2012 era.

  • Like 1
Link to comment
22 minutes ago, hooovahh said:

I remember a presentation by Jack Dunaway years ago at NI Week I think that talked about some of the event behaviors, and how it has changed in some releases.  This was in the 2012 era.

Then, a couple of years later, NI completely redid how events work behind the scenes which corrected some things Jack mentioned, complete with an NI Week presentation.

Link to comment
15 hours ago, Darren said:

Antoine is correct, those diagrams should function identically.

Should they?

18 hours ago, hooovahh said:

There are some behaviors in LabVIEW that either weren't well defined, or up for interpretation on how it should work.

How about this?

image.png.66581bbecf1ef11074321285f658ab74.png

I have expected this argument to be made (for events) for a few years now. It would break almost all event structure code if it were changed to be in line with the other structures.

 

Link to comment

You’re saying that an event registration terminal should behave like a tunnel?

They are not the same thing as the name already says (and the symbol shows)! It’s also more like a shift register although the right side of a shift register can’t be unwired.

And the behavior makes sense. For tunnels it can be a pitta to have to wire each output but it’s also desirable that it can be easily “reset”. And that behaviour was defined ca. 1986! For event registrations it is almost never needed to connect the right side terminal (I did that maybe once or twice in my entire LabVIEW programming). Alternative would have been to make only a terminal on the left side but then you couldn’t dynamically register an event.

Inconsistent? Maybe if you take a puritan look, ,useful? Definitely!

And I can assure you the LabVIEW team debated over this probably several weeks if not months before deciding on the current solution. 

The only improvement I could think of nowadays is to allow to hide the right side terminals!

 

Edited by Rolf Kalbermatter
Link to comment
26 minutes ago, Rolf Kalbermatter said:

The only improvement I could think of nowadays is to allow to hide the right side terminals!

How about giving us the ability to define right side terminals (like "Panel Close?") and give us the ability to allow an event case behave like a callback? That'd be a fantastic improvement.

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.