From 04:00 PM CDT – 08:00 PM CDT (09:00 PM UTC – 01:00 AM UTC) Tuesday, April 16, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW Idea Exchange

cancel
Showing results for 
Search instead for 
Did you mean: 
altenbach

Option to discard stale entries in the event queue

Status: Completed
Implemented in LV 2013

Currently problems occur with "analog" type events (value changed of a slide, cursor move, etc.) because too many intermediary events will be queued up. If the event case takes any finite amount of time to execute, we get a huge buildup of events.

 

A very illustrative example and a possible workaround can be found here. While the workaround works well for unique cases, it gets complicated quickly if event cases are shared by several controls (e.g. "graph cursor move" or "slide value changed" in the same event case).

 

What we need is an option to set the queue size of the event queue for each unique event. For example if a value change event occurs on the slide, and the same event with a slighly older value already exists in the event queue, the new event should overwrite the old event, keeping the queue at size=1 for that particular event. It should not touch queued up events of other controls, etc. of course.

 

Most likely we only need two choices: (1) infinite queue (current behavior), (2) single element queues (only the newest event of each configured event is kept in the queue). It could be implemented with a checkbox on the event configuration dialog e.g. : "[x] Discard stale events".

 

Of course if should be configurable for each unique event, not just for each event case.

 

(This idea is along the lines of Marc's idea here  and would also potentially provide a solution for Shane's xcontrol problem). 

21 Comments
JackDunaway
Trusted Enthusiast

I needed this very idea today, and almost posted it, but figured it was such a "special" case that I could not drum up support. Here's what happened:

 

I have a UI VI with two parallel loops: one handled events, and the other handled the consumption of a notifier. I wanted to have one unified consumer loop, where the notifier could act as an "event", but only handled the most recent unhandled event (single element queue). I ended up just converting the notifier into a dynamic event, and will "hope" that it always keeps up. Configuring that event to act as a SEQ would have been a perfect solution for having one unified consumer loop that consumed from multiple sources.

 

Kudos.

Message Edited by mechelecengr on 07-24-2009 05:13 PM
altenbach
Knight of NI

> but figured it was such a "special" case...

 

Looking at most of my code, I constantly run into "event buildup" problems. I currently solve them as described by comparing the values from the event terminal with the current values. Here are two code examples.

 

 

 

On the left is the quoted example above. If the value from the event terminal differs from the current value, we execute the empty case, quickly draining all accumulate stale events. We are guaranteed that the last event executes, bringing the result up to date with the latest slide value.

 

On the right we do a similar thing for a cursor move event. Since there are several cursors we need to get the latest position of the moved cursor via a property node. Movement of any cursor requires some complex recalculation and redrawing of the graph for interactive adjustment by the user with constant visual feedback. Without the workaround, events would quickly accumulate, making the UI unusable. With the workaround user interaction is near perfect, even on a slow computer.

 

Sure, if all events only do some very simple math and execute in microseconds, none of this is really needed.

 

I also have been using a different workaround, imposed by the limitation that the two events cannot easily be combined into a single event case because the event terminals don't match. Basically, I have the bulk recalculation based on cursors and slide in the timeout case and empty cases for the two operations where I set the new timeout to 0ms via a shift register. Now events execute very quickly until the queue is empty and the timeout is triggered. The timeout case resets the timeout to -1 and things go back to sleep after the final recalculation until the next user interaction occurs. This method also has limitations, because sometimes the timeout case is used for something else. 

 

(also note that "lock front panel until event completes" is of course disabled. Having this option enabled would make things even worse.)

 

The ability to prevent event accumulation would really help in many of my programs, significantly simplifying the code.

Message Edited by altenbach on 07-24-2009 04:00 PM
JackDunaway
Trusted Enthusiast

Consider this as a viable method for cases other than user inputs:

 

Compare the time on the event to the current msec timer, and conditionally process the event only if it's within "t" msec ago from "now".

 

My notifier was being fed from data spooled UDP from a remote computer. Since I never know the contents of the datagram, I cannot compare the "Value" in the event to a "current" value (such as current mouse position, or current value of the slider). The only piece of information that can determine "staleness" in this case is timestamp.

 

Previously, with the separate notifier consumer loop, the indicator would "hang" for a second or so if another process starved the loop, but then it would pick right back up with the most recent value - no big deal. Once I converted the spooled data to be passed on as a dynamic event, however, when it picks back up after hanging, it makes about 50 really fast updates that have been queued. Big deal now, because the indicator looks stupid rushing to make up for its tardiness. The solution: throw out those stale events that are more than ~50msec old. I may get a couple of "rushed updates", but a couple is invisible and therefore acceptable (whereas 50 is neither invisible nor acceptable!).

 

Note: In this method, you are NOT guaranteed that the "most recent" event will be executed! If the most recent event was 60msec ago, and you filter at 50msec, then it will not update! This is why I want R&D to create the "single element queue" configuration for event structures!!!!

Message Edited by mechelecengr on 07-24-2009 08:56 PM
JackDunaway
Trusted Enthusiast
I would particularly be appreciative if we got at least a teaser from R&D if this idea is feasible, useful, and/or on the radar.
AristosQueue (NI)
NI Employee (retired)

> I would particularly be appreciative if we got at least a teaser

> from R&D if this idea is feasible, useful, and/or on the radar.

 

I pinged a couple folks on Friday, but I think they're on vacation. It may be a while... remind me again if I don't post back within a couple weeks. 

Intaris
Proven Zealot

This is badly needed, not only for my XControl problem.

 

I think it perhaps important to highlight THIS thread also in connection with changing Events or EventHandler behaviour.....

 

Yummy, wiring up notifiers and Queues to the Event handler..........

LabBEAN
Active Participant

Another use case for R&D to consider when determining an implementation:

 

Producer (GUI) Loop captures slider value change events

Consumer (Hardware) Loop updates a DAQmx analog output channel

 

Currently we use dynamic event registration to register for the slider value change event.  When the event occurs, we unregister the event and enqueue the value to the Consumer (Hardware) Loop which updates the DAQmx channel.  As soon as the DAQmx update is complete in the Consumer (Hardware) Loop, we enqueue back to the Producer (GUI) Loop to re-register for the slider value change event.

 

This prevents the accumulation of events while the hardware is busy and keeps the analog output synchronized with the slider.


Certified LabVIEW Architect
TestScript: Free Python/LabVIEW Connector

One global to rule them all,
One double-click to find them,
One interface to bring them all
and in the panel bind them.
Intaris
Proven Zealot

LabBEAN, I made essentially this wish HERE.

 

Shane.

Message Edited by Intaris on 07-30-2009 10:39 AM
Mads
Active Participant

All events which lose relevance when they are repeated and which have a tendency to be repeated multiple times within a short timespan- rise this problem. Window resizing and cursor movements are good examples. 

 

Que size of 1 would not be the correct solution in most cases unless you also make it a lossy que. The option in the event case dialog's event specifier section should be to just keep the latest instance of the event from the given event source. It could be a checkbox in the list, named "Ignore previous" e.g...

Intaris
Proven Zealot
Either that or an option to read out the WHOLE queue just in case the user doesn't want to lose any information.  Processing multiple Events in one go could be a lot faster than having to iterate through them (especially since front panel activity could be largely avoided for he multiple instances).