Jump to content

Intending to Use Event Structures to Manage "Pop Up" UIs, any warnings?


AlexA

Recommended Posts

rather than a Queue, where the sender and receiver share the same reference - decouples processes and simplifies philosophical (and practical) issues like ownership and lifetime.

Named queues :)

But in a less confrontational aspect. The issue I have is with the idea of "stuffing". That you create a registration, maintain it and generate events, whilst not consuming. At least with a queue you can monitor the elements and even restrict the size (for the scenarios where you want to "stuff")..

Edited by ShaunR
Link to comment

Named queues :)

Yeah, I keep all mah named queue refs in mah global vars to make the programming more handier. :yes:

But in a less confrontational aspect. The issue I have is with the idea of "stuffing". That you create a registration, maintain it and generate events, whilst not consuming. At least with a queue you can monitor the elements and even restrict the size (for the scenarios where you want to "stuff")..

Again, this boils down to best practices. SubPanelling implies asynchronicity, which can lead to race conditions and missed messages. One notable example is the Shutdown event -- it's possible that a system can issue the shutdown command the moment after a command to begin SubPanelling has begun. (We would agree here it's a bad programming practice to "stream" events into an unhandled queue for too long; that would probably be an abuse of pre-registration.)

Link to comment

Yeah, I keep all mah named queue refs in mah global vars to make the programming more handier. :yes:

I don't use refs at all ;) The main reason I use named queues is that it is part of the message "routing".

Again, this boils down to best practices. SubPanelling implies asynchronicity, which can lead to race conditions and missed messages.

This is why queues are (IMHO) preferable under these particular circumstances since you don't miss messages and race conditions are alleviated (although not necessarily eliminated depending on your macro view). With queues you also have asynchronicity but you can also guarantee the order which, for control, is highly desirable..

One notable example is the Shutdown event -- it's possible that a system can issue the shutdown command the moment after a command to begin SubPanelling has begun. (We would agree here it's a bad programming practice to "stream" events into an unhandled queue for too long; that would probably be an abuse of pre-registration.)

Or you could begin sub-paneling (not quite sure if I'm understanding what this is correctly), send the shutdown and the sub-panel would appear then disappear as each element was removed (or you could flush it on the off chance it hasn't been enacted yet). I just think for this particular scenario, queues have many advantages over events, not least that you don't "lose" messages just because someone isn't listening.

Edited by ShaunR
Link to comment

Just to update the people on where I'm at and what route I decided to take.

So I was designing UI's for my various experiments, and I didn't want to have multiple loops running in each UI (event handler and external message handler accepting messages via queue). This was the prime motivator for trying to figure out how to pass info to the event structure in each UI.

In the end, I decided to shy away from this and only use event structures for handling user button presses. Each UI now maintains an event loop to handle its front panel objects, and a parallel while loop operating as a message handler which effectively handles displaying updates from the code. In actuality, messages to the external environment pass from the events loop to the parallel message handler loop before they are put on the "output messages" queue. The reasoning for this being that otherwise, there might be some case in which both the message handler (reacting to some external event) and the event structure (acting on user input) are trying to load messages onto the output queue in a race condition type of behaviour. In effect (I hope), simplifying interaction with the UI for external components (single point of interaction).

This maintains a sort of consistency with the other "modules" in my code, which are almost always some message handler and a parallel process, either a measurement type process, or in the case here, a UI.

Anyway, just thought I'd update with some reasoning.

Link to comment

By convention, the Event Registration Refnum is wired exclusively to one and only one Event Structure, and this wire is never branched -- the exact same convention as the "Register for Events" node. The difference? The User Event ref remains private to the containing Messenger class; no naked refs are exposed to be manipulated with User Event prims by callers

When I tried the event registration refnums, they were private data in one of my classes so they needed accessor VI's to be of use to any VI that wasn't a class member. That means that I had no choice except to share the event registration refnum, which turned out to be a bad idea for my use case since it doesn't really allow multiple subscribers. If I just expose the event refs,then its easy for any VI that wants to consume the event to subscribe. I don't find it ever necessary to preload event queues since I don't use the events for any kind of input control - they are only used to publish data to subscribers. More importantly, how do you accomodate multiple subscribers?

Link to comment

When I tried the event registration refnums, they were private data in one of my classes so they needed accessor VI's to be of use to any VI that wasn't a class member. That means that I had no choice except to share the event registration refnum, which turned out to be a bad idea for my use case since it doesn't really allow multiple subscribers. If I just expose the event refs,then its easy for any VI that wants to consume the event to subscribe. I don't find it ever necessary to preload event queues since I don't use the events for any kind of input control - they are only used to publish data to subscribers.

Ah, yes, I ran into this limitation myself before realizing I had made a fundamental mistake. The Event Registration Refnum should not be part of the Messenger Class Private Data - the User Event Ref (the Messenger) is what needs to be stored in the Class Private Data. When creating a new mailbox, you can call this method N times for each of your N subscribers. This falls into the "messenger is decoupled from the mailbox" feature of User Events.

Note that once an Event Registration is created by this method, the ownership is passed out of the class and to the subscriber (the VI with the Event Handler Structure that uses the refnum). Here's a screenshot of that VI:

post-17237-0-24145900-1348628886_thumb.p

Link to comment

By convention, the Event Registration Refnum is wired exclusively to one and only one Event Structure, and this wire is never branched -- the exact same convention as the "Register for Events" node. The difference? The User Event ref remains private to the containing Messenger class; no naked refs are exposed to be manipulated with User Event prims by callers.

Erm, Jack this is not technically correct.

Once an event fires, the naked event refnum IS exposed as part of the data within the event structure allowing foolish of malevolent programs to destroy the user event refnum.

I have an idea on the labview Idea exchange to remedy this but it has almost zero traction.

Shane.

  • Like 1
Link to comment

Random thoughts on User Events versus Queues:

— The event registration refnum is a queue, and it is more instructive to compare this queue to regular Queues rather than compare User Events to Queues. They have different extra features, but in basics they are the same; they serve up the enqueued items to one receiver in order. And one should not have more than one receiver per queue.

— The event structure itself can receive from multiple queues. In particular, the statically registered events are in a separate queue from any event reg. refnum attached dynamically. The order that items are served up from different queues is determined by timestamp. This means that near simultaneous events placed in different queues cannot be relied upon to be received in order. However, items from the same queue will always be in order, which means one can use a User Event to reliably carry messages to a process.

— A User Event can be thought of as an array of queues; firing the Event is the same as enqueuing to all the queues, and the Event Registration Node serves to add its queue to the array. When created, of course, the User Event is an empty array.

Random random thoughts:

— a “name” is a reference, the same as a refnum.

— “subpaneling” is a silly term :)

  • Like 1
Link to comment

In rare cases the event queue can get muddled if the events are sent more quickly than the timestamp resolution can take care of. This leads to the events possibly being received IN THE WRO_NG ORDER. This is within the same event queue, and can be provoked even with the same event.

It has been reported and apparently the timestamp will include a more robust mechanism in future to avoid this....

In this regard, the queue vs events comparison gets a bit weird as the order in a Queue CANNOT be muddled (AFAIK).

Shane.

Ps I'm still a big event fan though.

  • Like 1
Link to comment

— A User Event can be thought of as an array of queues; firing the Event is the same as enqueuing to all the queues, and the Event Registration Node serves to add its queue to the array. When created, of course, the User Event is an empty array.

Whilst the mechanics may be thought of in that way and indeed, both may be coerced to emulate the properties of the other, they are actually different topologies. Queues are "many-to-one" and events are "one-to-many".

— a “name” is a reference, the same as a refnum.

....but with no type!

— “subpaneling” is a silly term :)

Agreed :)

In rare cases the event queue can get muddled if the events are sent more quickly than the timestamp resolution can take care of. This leads to the events possibly being received IN THE WRO_NG ORDER. This is within the same event queue, and can be provoked even with the same event.

It has been reported and apparently the timestamp will include a more robust mechanism in future to avoid this....

In this regard, the queue vs events comparison gets a bit weird as the order in a Queue CANNOT be muddled (AFAIK).

Shane.

Ps I'm still a big event fan though.

I've been bitten by these sorts of things in the past too.....they are a real bugger to track down and the solution is invariably to use a queue instead.

Edited by ShaunR
Link to comment

In rare cases the event queue can get muddled if the events are sent more quickly than the timestamp resolution can take care of. This leads to the events possibly being received IN THE WRO_NG ORDER. This is within the same event queue, and can be provoked even with the same event.

Can you provide a reference? I’ve only seen mention of that problem when the two events are in different event queues in the same event structure, such as a statically-registered event and a dynamically-registered one.

Link to comment

Whilst the mechanics may be thought of in that way and indeed, both may be coerced to emulate the properties of the other, they are actually different topologies. Queues are "many-to-one" and events are "one-to-many".

You can use User Events "many-to-one” too. Create an Event, register for it yourself, then pass the Event to other processes so they can send you messages.

Link to comment

Can you provide a reference? I’ve only seen mention of that problem when the two events are in different event queues in the same event structure, such as a statically-registered event and a dynamically-registered one.

I had the problem with an XControl which I was peppering with events to show that XControl value updates often lag behind the calling VI. Doing this I saw that when queuing up many events fast enough, the order became mixed up. I DO remember making a post about this on the NI site but for the life of me I can no longer find it. I have found a link of mine which points to nirvana, so maybe my post was removed for some reason...

Here's a post from someone else having the same problem essentially.

Shane.

How do I edit my posts?

The link I wanted to place int eh last post is not really related.

Please ignore me while I go insane.

Thank you.

Shane.

Link to comment

Erm, Jack this is not technically correct.

Once an event fires, the naked event refnum IS exposed as part of the data within the event structure allowing foolish of malevolent programs to destroy the user event refnum.

I have an idea on the labview Idea exchange to remedy this but it has almost zero traction.

Shane.

Yes, yes, I know... and I have come to agree with you... hold on, brb... (writing a response on that thread)... OK, back, here's the response copied: "Two and a half years later... I'm on the same side of the fence as Shane now. The points I mentioned above represent anti-patterns I was using at the time, and have since found much greater success wrapping messengers inside a class with a well-defined API. So... Kudos!" which can be read here. Thanks, Shane! It's taken me a while to catch up to you :yes:

In rare cases the event queue can get muddled if the events are sent more quickly than the timestamp resolution can take care of. This leads to the events possibly being received IN THE WRO_NG ORDER. This is within the same event queue, and can be provoked even with the same event.

Can you provide a reference? I’ve only seen mention of that problem when the two events are in different event queues in the same event structure, such as a statically-registered event and a dynamically-registered one.

As far as I'm concerned, this "can't guarantee order" is sort of an urban legend, with a grain of truth. I remember vividly Ton's example, and even though I think there's another thread, here's one instance. As long as you're OK with and understand that these two events are fired synchronously, they are stuffing two discrete queues operating asynchronously, so the order in which they are handled cannot be guaranteed. And here's a screenshot from his post that illustrates the "problem":

post-17237-0-40020200-1348677374_thumb.p

— The event structure itself can receive from multiple queues. In particular, the statically registered events are in a separate queue from any event reg. refnum attached dynamically. The order that items are served up from different queues is determined by timestamp. This means that near simultaneous events placed in different queues cannot be relied upon to be received in order. However, items from the same queue will always be in order, which means one can use a User Event to reliably carry messages to a process.

This is a great explanation of why the "can't guarantee event order" should be considered a false urban legend. By the way, James, many great "random thoughts" that effectively provide a good practical understanding on considerations when using User Events.

Link to comment

I had the problem with an XControl which I was peppering with events to show that XControl value updates often lag behind the calling VI. Doing this I saw that when queuing up many events fast enough, the order became mixed up.

Actually, I’ve seen this same effect with an Xcontrol of mine. The same effect occurs if you set the control to “synchronous” and hit the terminal. Note, though that you aren’t directly firing events here; you’re triggering a property, and whatever code behind the scenes is firing “Data Changed” events into the Xcontrol. And the associated data isn’t packaged with the event, it’s provided via the “Data In” input terminal. It isn’t clear that the problem is in the event system itself.

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
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
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.