Leaderboard
Popular Content
Showing content with the highest reputation on 10/19/2011 in all areas
-
So tonight I gave a presentation on QSMs at the local LUG and it got me thinking about the differences between a "slave" and a "consumer." Thinking I'd get some information by going to the source, I opened the Master/Slave and Producer/Consumer templates included with Labview. I've never taken the classes that cover these patterns, so I have no idea how NI intends for them to be used. But looking at these two block diagrams I see one pattern implemented using two different transport mechanisms. Aside from the transport, how exactly are these patterns different? The slave help text (copied to the bd) implies a functional difference I don't see. What am I missing?1 point
-
I don't quite understand what you are referring to here. I provided the resetting of the button via a local at the beginning of the program as just an example (albeit a common usage scenario). Clearly, you can reset it anytime you want.1 point
-
Here's the original, with a few options for 2011: http://forums.ni.com/t5/LabVIEW/How-To-Setup-your-LV-Icons-so-you-can-tell-versions-apart/m-p/16651921 point
-
It's not the only thing they have in common. In both of them all messages to a specific slave loop comes from a single place. That, more than anything else, is what defines a slave in my mind. I don't think lossy vs. lossless is one of the defining characteristics of slaves or consumers. I suspect the template uses notifiers simply because they allow easy 1-to-many communication. I use queues instead because most of the time I want lossless master/slave communication. Possibly, but I don't believe they would have put it in there unless someone had found it useful. The template is just a starting point. It's obvious there are ways NI intends it to be used, it's just not obvious what they are. Maybe they consider it okay to replace the notifier with queues? I do agree the M/S template doesn't seem to map very well to code I've encountered in the wild.1 point
-
Oooo.... I like that. I did run into a bit of trouble when I went to implement an example. I didn't create protected accessors to the MessageQueue's private data. This means the PrefixedMessageQueue class has to contain an instance of its parent and you have to override every method to unbundle the parent object. Seems kind of wasteful and unnecessary... Here's an example of the EnqueueMessage override: And here's an example of how it would be used: (I'll have to think about releasing a LapDog.Messaging minor update that includes protected accessors. That would allow you to only override the enqueue methods instead of all of them, but I need to ponder it for a bit.) ------------ It's hard to follow what you're describing. Can you post code? PrefixMessageQueue.zip1 point
-
Fair concern. My intent isn't to create more confusion, it's to create more clarity. When somebody says they're using producer/consumer, all that tells me is some sort of information is going from the producer loop to the consumer loop. Anything beyond that is a guess unless I see their code. So what are the critical characteristics of a producer/consumer pattern in your opinion? Is it multiple senders to a single loop? The template has only a single producer and a single consumer, yet it is producer/consumer. Does it require that information always flow in a single direction, from the dedicated producer loop to the dedicated consumer loop? That's how the template shows it, but one way communication seems to me to limit its usefulness. If the consumer is sending information back to a producer, is it no longer producer/consumer? If not, what is it?1 point
-
1 point
-
Those are all just characteristics of the different transport mechanism. My (poorly made) point was that the transport mechanism alone isn't enough (imo) to justify a different pattern name. This is much more in line with my perception of what it means to be a "slave," and as you pointed out, they both fall into that category. Ahh, these are the key points I was missing. The intent of the Master/Slave is to produce more slave loops while the intent of the Producer/Consumer is to create more producer loops. Rereading the context help I see they do mention using multiple slave loops in the M/S documentation. (I trust they cover these in the class that teaches these patterns, because the included documentation doesn't make it very clear.) The other thing that struck me as odd was wiring the dequeue/wait error terminals into the case structure. That seemed rather restrictive as it only allows for a go/no go command. I assume the intent is something along the lines of this: I'll add that I don't think the "Producer/Consumer" name is the best way to describe that pattern. I view producer and consumer as roles each loop plays at different times. Any loop sending information to another loop is a producer and the receiving loop is the consumer. In the code above the loops just happen to never change roles. To be honest I'm not sure what to call it. It's more of a statically defined publish/subscribe.1 point
-
Thanks everyone for their input - all non-functional comments and suggestions have been reviewed with respect to updating the code Jim posted. This OpenG Review is now closed. Please start a new thread to discuss new changes to this VI. Please PM me if there are any issues with this thread.1 point
-
A third option would be to put the functionality into your MessageQueue class. Make a "PrefixedMessageQueue" child class with a "Prefix" data item, an extra "Specify Message Prefix" method, and an override of "Enqueue Message" that adds the prefix to the message name before calling the parent method. Use this child for the master's incoming queue and, just before passing it to each individual slave, call the "Specify Message Prefix" method with prefixes such as "SerialDevice:DeviceB:" or whatever. The advantage of this method is that you only have to create the child class once, rather than modifying each slave to have a name property, or making a separate adapter class for each slave class. -- James1 point
-
Right - unless your method is already child or isn't going to be part of an inheritance scheme, and that's called method cloning (which is not supported in native LVOOP, but is with jgcode's LVOOP Assistant and Endevo's GDS).1 point
-
Are you changing the code at all? If not, then there is no need for each child class to have that VI, just call the parent VI.1 point
-
Yes, a dirty little secret of mine is still even after 15 years, I find bugs in my code relating to "blindly" wiring error clusters through without thinking about it. Seems many of us are guilty of that in this thread. I find one of the most overlooked things when designing an application framework, no matter how simple the application, is at what level(s) the errors are handled. I never thought of looking to see if the notifier was destroyed or not to check between a real timeout versus a notifier being destroyed. Alternatively, you could use the error status to signal the boolean (and also force execution order). Edit: Withdrew a snippet I posted, problem with it.1 point