09-24-2019 05:47 AM
Hello everyone,
I have a question I could not find an answer for: when we look at the templates provided from NI, we see 2 types of release queue connection. See the attachments.
I would like to know what is the difference. Why is it done in the different ways?
The direct connection is from the Producer Consumer Data template, the other one is with Events template.
Thank you for your responses!
09-24-2019 06:09 AM
In my opinion, both are wrong. The Consumer should be the one maintaining the queue. So the Release Queue should be done inside of the consumer loop when it receives the "Stop"/"Exit" command.
09-24-2019 06:10 AM
Well both are from the NI templates: in new>> design patterns...
09-24-2019 06:16 AM
@rajiv85 wrote:
Well both are from the NI templates: in new>> design patterns...
That aside, the benefit of the consumer releasing the queue is that it can choose to do so when it has done whatever it wants with elements before (or even after, perhaps) the "stop" message.
The downside is you must implement some stop signal. If your queue is for transmitting data, then the error wire (queue was released somewhere else) is the simplest solution, but it risks throwing away data etc. Passing a message with each data chunk requires more effort (bundling, unbundling etc) or alternatively a separate additional queue.
If I were to guess at the reason for the templates, I'd say it's done that way for the sake of simplicity.
09-24-2019 06:20 AM
Alright but specifically: why is one release queue direct and the other one is passing all around the loop to the other side?
09-24-2019 06:51 AM
There is no particular reason. The execution of both will be after the loop because of the error wire that exits the loop.
Normal practice is to send the wire through the loop. One reason not too might be so you don't have to wire the queue wire across all the cases of the event structure that don't use the queue reference.
09-24-2019 07:02 AM
@rajiv85 wrote:
Alright but specifically: why is one release queue direct and the other one is passing all around the loop to the other side?
You'll notice that the event structure has no queue output. Really this is a "Save the Developer From a silly mistake" as the Event srtucture output tunnels default to "Use Default if Unwired" and the default data for a reference datatype is "0" or, an invalid reference, NOT the reference that you want to close when the Event loop stops! (and a darned easy mistake to make with a bunch of head-scratching to work out that someone added an event without wiring the queue reference through it)
The Case structure On the other hand, has output tunnels set by default to break the code if they are unwired from the inside in any Case so, the chances of adding a case with a bad queue reference out are significantly reduced.
09-24-2019 07:07 AM
@cbutcher wrote:
That aside, the benefit of the consumer releasing the queue is that it can choose to do so when it has done whatever it wants with elements before (or even after, perhaps) the "stop" message.
Another benefit: the consumer maintains the lifetime of the queue (assuming the consumer also creates the queue). Imagine a dynamic system where multiple threads are spawned that all send data to the same consumer. If producer 1 created the queue and then went out of memory for whatever reason, the queue is gone with it. This makes it so all of the other threads cannot use it and do their job. So I consider it extremely important that the consumer of the queue initializes and closes the queue.
09-24-2019 07:26 AM
@crossrulz wrote:
@cbutcher wrote:
That aside, the benefit of the consumer releasing the queue is that it can choose to do so when it has done whatever it wants with elements before (or even after, perhaps) the "stop" message.Another benefit: the consumer maintains the lifetime of the queue (assuming the consumer also creates the queue). Imagine a dynamic system where multiple threads are spawned that all send data to the same consumer. If producer 1 created the queue and then went out of memory for whatever reason, the queue is gone with it. This makes it so all of the other threads cannot use it and do their job. So I consider it extremely important that the consumer of the queue initializes and closes the queue.
Not exactly! notice that the "Force Destroy" input is unwired (default FALSE.) The queue is not destroyed until every "Obtainer" has released it. I will however, concede that I prefer to NAME my queues when they are being dynamically used like you describe.
09-24-2019 08:25 AM
@JÞB wrote:
I will however, concede that I prefer to NAME my queues when they are being dynamically used like you describe.
I am not a fan of Named Queues. Burned once a long time ago. I much prefer using an Action Engine that is private in a library and have public interfaces to that AE to send data/commands to my consumer. This way, I know exactly what I can receive and the consumer (also part of said library) is in full control of the queue.