LabVIEW Idea Exchange

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

More native queue metrics

Status: Declined

Any idea that has received less than 4 kudos within 4 years after posting will be automatically declined.

We often need to use lossy queues for best-effort data transmission between code modules. And in those cases, we *accept* that we might drop some messages, but we would like to track *how many* we have dropped.

 

We end up having to do a lot of explicit coding to

  • check the "overflow" flag on the lossy enqueue operation
  • count those overflow instances
  • aggregate overflows, in cases where we are enqueuing in multiple locations (e.g. multiple produces for a single consumer)

I have considered making a special class to contain in its private data a queue and a DVR for overflow_count, but the problem is that it wouldn't be natively polymorphic (would not support all data types like the queue primitive). Sure, I could do it with variant data in the queue, or even flattened strings or whatever, but that adds some additional processing overhead, and unless we use xnodes, it muddies up the API with downstream deserialization.

 

Idea: please consider adding an overflow counter to the base queues, with a new output to the "flow status" primitive to query number of overflows.

Might also be nice to count total number of items queued.

And, as a bonus, add a mechanism to reset the counters, so we could do something like query these counts and reset them at 1Hz, resulting in enqueue_rate and overflow_rate values in Hz.

 

 

Here's a rough approximation of how I envision the under-the-hood implementation for the "lossy enqueue" method:

 

queue_metrics.png

7 Comments
Mr._Jim
Active Participant
I use lossy queueing pretty frequently for various use cases, and though I haven't needed this yet I could see it being useful, especially for diagnostic purposes. I'm glad you're suggesting a new status primitive, since the "Get Queue Status" node can't really easily take on any new functionality. I agree that the class you're implementing isn't nearly as good as the truly polymorphic primitives. I'd also be worried about multiple consumers blocking each other's execution due to the DVR. (Probably not a big deal unless you had a lot of consumers) ...but hey, the class is better than nothing and it will probably get you through what you're trying to do right now.
AristosQueue (NI)
NI Employee (retired)

TurboPhil:

Tangent: There's a bug in your picture: Looking at your diagram, you need to put the Enqueue primitive inside the In Place Element Structure to avoid a race condition. Anyone who accesses your data structure could get stale data if the enqueue has already happened but has not had time to update the accompanying data structure. It gets worse the more parallel enqueue operations you have going for the same queue. You can make this error impossible -- just put the queue refnum inside the DVR's cluster so no one can access it without getting the DVR lock first.

 

Regarding the idea: I am extremely loathe to add any weight to the primitives for rarely used functionality, especially when there's a solid workaround available. If you can find evidence of a high need for tracking these metrics across many users, I'd be more open to the idea.

 

The biggest concern I have is that the Get Queue Status is the greatest source of bugs in applications using the queues. I would hate to add another status function that only encourages the problem. People abuse Get Queue Status primitive in the same way they abuse the Not A Refnum primitive. I'd be more open to just putting more outputs on the Enqueue Lossy primitive itself so that the data is harvested synchronously with the enqueue action, avoiding the race condition.

TurboPhil
Active Participant

AristosQueue:

Good call on the bug in the picture. I just whipped that up for illustrative purposes; it's not something we run anywhere.  I just wanted to describe in a picture what I meant, while also showing how lightweight the underlying implementation could be. Presumably in the native C/C++ implementations of the existing queue natives could have a small tweak to support counting overflows that would have minimal impact to performance.

 

To a rough approximation, I presume that the current lossy enqueue primitive is basically just a pointer to a memory location where the queue is stored (as a circular buffer), with an additional pointer/index to keep track of where in the queue we are (index in the circular buffer). So it seems like it would take very little to have the queue reference be augmented to include a pointer to a U32 counter (or just put it immediately adjacent to the buffer in memory), and then add the trivial steps of retrieve, increment, reset to that U32 based on teh selected operation.

AristosQueue (NI)
NI Employee (retired)

> seems like it would take very little

 

You're correct. Very little is a lot for primitives that try to execute in very tiny time frames. 🙂 I doubt that this would break the bank, but I still resist adding anything to them that isn't strictly necessary or isn't commonly used. The policy keeps them free of lots of little things that add up to a notable thing.

Mr._Jim
Active Participant
Shoot... forget what I said about DVR blocking and consumers, which didn't make much sense. I think I was multitasking one too many tasks. Duly noted, AQ, regarding the aversion to new primitives without very good reason - completely understandable.
AristosQueue (NI)
NI Employee (retired)

So, like I said -- talk to your associates who use the queues... if they need this kind of tracking, ask them to come add their kudos.

Darren
Proven Zealot
Status changed to: Declined

Any idea that has received less than 4 kudos within 4 years after posting will be automatically declined.