 GSinMN
		
			GSinMN
		
		
		
		
		
		
		
		
	
			10-04-2013 10:08 AM
I am working on an application that has several producer-consumer loop pairs, and noticed that the release queue function (in the template) relies on an error to let the consumer loop finish (error 1122). In an effort to avoid this, I have implemented a simple flow control method with error bundles, as shown in the included image, to prevent the queue from being released until after the loop is finished.
 
You will probably note that I removed the error case structure that is used in the template. The reason for this is that I need to be able to stop the loop at any time, even if there is no error, or when the dequeue is never called (I have several loops running in the application that rely on the same stop button). This in itself created a new issue, in that the loop would not run unless an element was queued, which means the stop variable would not be checked. Thus the loop would never complete. To overcome this, I invoked the timeout function on the dequeue element so that the loop would always run.
The problem with all of this is that it appears that the loop is running twice for each time the element is queued/dequeued, meaning that (in my specific case) the message is sent twice. Without the timeout implemented, the message is only sent once (but I of course have to abort the VI to stop it).
I'm looking for any ideas as to why this is happening. It actually occurs in several of the loops, regardless of of that the actual internal purpose of the loop is (sending messages, receiving message, logging data, etc.). Please advise.
Thanks,
GSinMN
 Neos
		
			Neos
		
		
		
		
		
		
		
		
	
			10-04-2013 10:48 AM
consumer loop will not run twice....it will run every time after 1000ms and the o/p value of the dequeue function will be default data type ( in your case ) empty string.
you need to learn proper design pattern, search it you will find a lot of related materials.
( anyways using timeout on dequeue makes it to poll, so unless required it's kind of loosing beauty of queues. )
 )
 RavensFan
		
			RavensFan
		
		
		 
		
		
		
		
		
	
			10-04-2013 10:58 AM
You should queue up a stop message in the producer loop when you wan the consumer loop to stop.
You do know that as you have it right now when an iteration of the consumer loop runs, reading the stop local variable happens very early in the loop, probably first. The dequeue will wait 1000 seconds until the timeout. Even if you have hit the stop button, the loop will iterate again because the value in the local variable will already be read as false. So the consumer loop will iterate again, now reading the stop value as True. the dequeue will wait another 1000 seconds until it times out. The TCP function executes, then the loop will stop because of the true boolean on the stop terminal and all the code inside having been executed.
 KathrynB
		
			KathrynB
		
		
		
		
		
		
		
		
	
			10-04-2013 11:05 AM
The best thing you can probably do is re-address your basic architecture. If you alter the consumer loop queue to be a cluster of variant and an enum running a state machine you gain a LOT of power over your system. Especially if the Enum is a typedef.
For the situation you have shown:
Producer Loop:
Event - Need to send a message (no idea of sepcfics, it's not shown):
Populate the Consumer Queue with enum value of "Send Message" and the variant with the message to be sent.
Event - "stop": Valut Change (the one shown):
Populate the Consumer Queue with enum value of "Stop" and the variant with a Boolean of True.
Consumer Loop:
Take away the timeout
Deque an element and unbundle it
Wire the enum into the selector of a case structure and the variant to the edge of the structure
For the case "Send Message" cast the variant to a string, then send it out over the TCP as shown - if you wire anything to the conditional terminal of the while loop make it a FALSE constant (do not quit the loop!)
For the case "Stop" cast the variant to a Boolean and wire it straight out to the conditional terminal.
It is a little more complicated, but does have the elegance of stopping everything in a known order (as you also can't guarantee in the image shown that a message won't have been requested, but the consumer loop stop before the message is dequed, unlikely, but not impossible) and being incredibly flexible for extending in the future.
 crossrulz
		
			crossrulz
		
		
		 
		
		
		
		
		
	
			10-04-2013 11:21 AM
As already stated, you should send some sort of stop command to your consumer loop and don't use the timeout. With your given example, I would send an empty string as my stop command. You obviously aren't going to send an empty string, so it makes sense as a stop command. For arrays, I like to use empty arrays. I find this is easier than creating a cluser with the data type and an enum to tell the command.
10-04-2013 01:14 PM
Hello All,
Thank you for your responses. I appreciate you taking the time. To clarify a few things:
Neos, yes I am aware that the loop will run continuously every 1000 ms. That was the point so that it will continuously poll the stop variable. The problem is that it sends the message twice. Perhaps the title was mileading.
RavensFan, Thanks for reminding me about the order of executuion. Yes, the stop function could be implemented differently, and I will likely add a sequence structure to ensure proper order for the other functions (most of which are not shown). However, the main problem is that the message is sent twice when I dequeue the element, not when I stop the VI.
KathrynB and crossrulz, the diagram I sent was meant as only a representation of the concept I am testing. My actual VI/Application is much more elegant, and does indeed incorporate things like bundled elements and enums. I thought this easier than to show all of the details.
Thanks to all,
GSinMN
 RavensFan
		
			RavensFan
		
		
		 
		
		
		
		
		
	
			10-04-2013 02:13 PM
@GSinMN wrote:
RavensFan, Thanks for reminding me about the order of executuion. Yes, the stop function could be implemented differently, and I will likely add a sequence structure to ensure proper order for the other functions (most of which are not shown). However, the main problem is that the message is sent twice when I dequeue the element, not when I stop the VI.
It didn't show us your code where things are being enqueued.
With what you've shown, I don't see any reason for a message to be sent twice.
Attach your VI so we can investigate.
 Yamaeda
		
			Yamaeda
		
		
		
		
		
		
		
		
	
			10-04-2013 09:44 PM
You shouldn't use the Stop local in that design, but queue an Exit command. In this case you can send Exit as text and use a case around the TCP send.
/Y
 drjdpowell
		
			drjdpowell
		
		
		 
		
		
		
		
		
	
			10-07-2013 03:54 AM
@GSinMN wrote:
I am working on an application that has several producer-consumer loop pairs, and noticed that the release queue function (in the template) relies on an error to let the consumer loop finish (error 1122). In an effort to avoid this...
First thing you should ask is if you have any reason to change the design at all. Using the release of the queue to serve as a shutdown message for the loop serving the queue isn't a bad design. It's much better than using a local.