SteveChandler Posted September 8, 2011 Report Share Posted September 8, 2011 This discussion about using variants vs. the native datatypes for messaging is continued from the LapDog Messaging Library v2 announcement thread here. Quote Link to comment
Daklu Posted September 8, 2011 Report Share Posted September 8, 2011 Just a quick response... I'm short on time. In practice I wouldn't register all controls on a front panel like that; instead controls (or groups of controls) which need special code would have their own case. But multiple controls can be registered for the same case, either statically or dynamically as an array of references. My initial thought is doing something like your example pushes UI code down into your application and is probably best avoided. Multiple controls can be registered for the same case (and I do it sometimes myself) but somewhere in your code you need to figure out exactly which control triggered the event and respond appropriately. I believe the best place to do that is in the event handling loop. I wasn't aware different units were considered separate types. To be honest I've always thought the units were more trouble than they were worth. I'll have to think about that for a while before deciding whether or not to add a variant message. I like your other examples too, though I need to study them some more before I comment on them. Quote Link to comment
SteveChandler Posted September 8, 2011 Author Report Share Posted September 8, 2011 Just a quick response... I'm short on time. I wasn't aware different units were considered separate types. To be honest I've always thought the units were more trouble than they were worth. I'll have to think about that for a while before deciding whether or not to add a variant message. I have not used units much but I see why they are different types. You get a broken wire if you try to multiply volts and temperature but you can multiply volts and amps. Pretty cool stuff for preventing bugs. [Edit: Hah. I told you I have not used units much. I just tried and indeed you can multiply volts and temperature. You end up with a new unit entirely s^-3 m^2 kg A^-1 K. It turns out that 5 degrees Celsius times 6 volts is 1668.9 of whatever those things are. Yea more trouble than they are worth ) Quote Link to comment
drjdpowell Posted September 8, 2011 Report Share Posted September 8, 2011 (edited) To be honest I've always thought the units were more trouble than they were worth. Tell that to the people who flew the Mars Climate Orbiter INTO the planet, rather than into orbit, because one of their software packages was outputing in pound-seconds what the rest of the program thought was Newton-seconds. I have not used units much but I see why they are different types. You get a broken wire if you try to multiply volts and temperature but you can multiply volts and amps. Pretty cool stuff for preventing bugs.[Edit: Hah. I told you I have not used units much. I just tried and indeed you can multiply volts and temperature. You end up with a new unit entirely s^-3 m^2 kg A^-1 K. It turns out that 5 degrees Celsius times 6 volts is 1668.9 of whatever those things are. Yea more trouble than they are worth ) It's a Volt-Kelvin. Volt = Joules/Coulomb; Joule = kg m^2 s^-2; Coulomb = Amp-second --> Volt = kg m^2 s^-3 A^-1 The base unit is often unintelligible to humans, but as soon as you create an indicator and set it to "Watts", or do any math operation that requires consistent units (add, subtract, greater than, etc.) you'll get a broken wire and realize you multiplied the wrong things. And you'll get an error from your power module if you send it a VarMessage to set power at 1668.9 Volt-Kelvin. Basically, the computer is too dumb to tell you your unit is weird, but it's far better than you at identifying when the physical dimension is not the same between two quantities. Units can be some trouble, and internal to a module you might want to not use them, but for public communication between modules (possibly written at different times or by different programmers) they extend the bug-preventing value of type-checking to physical dimensions and eliminate the need to remember what units other modules expect things in. -- James BTW: the link to the prior conversation is actually here. Edited September 8, 2011 by drjdpowell 2 Quote Link to comment
drjdpowell Posted September 8, 2011 Report Share Posted September 8, 2011 Multiple controls can be registered for the same case (and I do it sometimes myself) but somewhere in your code you need to figure out exactly which control triggered the event and respond appropriately. I believe the best place to do that is in the event handling loop. I'm not sure I understand. The event loop figures out which control triggered the event and sends a different message for each control ("Set>>{control name} in my example). Now, this example is only for controls that map well onto the required messages that the UI needs to send (User changed the pressure to 50PSI? --> Send "Set>>Pressure; 50PSI" message). If the relationship is more complex, then one needs custom logic in the UI for each control. -- James Quote Link to comment
SteveChandler Posted September 9, 2011 Author Report Share Posted September 9, 2011 Thanks James for the excellent writeup on units. I will definitely consider using them more after reading that. It seems like a pretty powerful thing that I have not been taking advantage of but probably should. BTW: the link to the prior conversation is actually here. Copy and paste error. I fixed the link at the top. Quote Link to comment
Daklu Posted September 15, 2011 Report Share Posted September 15, 2011 I've been thinking about this thread, but unfortunately I have been too busy to give it the response it deserves. I'm not sure I understand. The event loop figures out which control triggered the event and sends a different message for each control ("Set>>{control name} in my example). Yep, you're right. For the life of me I can't remember what I was thinking when I wrote that... However, that still means you have code down in your message receiving loop that requires knowledge of the UI. Specifically, it has to know the control's label. Labels are one of those things that--in my experience--developers tend to change without thinking too much. Writing algorithms that unnecessarily depends on label text causes brittle code. If I want to add a control, I just drop it on the front panel and give it the right name and it's done. <snip> I like things to be as "easy as hooking up a...wire". This is one area we differ. I'm more concerned with creating code that is sustainable rather than code that is easy to write. Often times these goals exert opposing forces on your design decisions. In fact, there is a noticable decrease in my code's sustainability when I try to make code that is "easy" to write. Readability, testability, extendability, etc., all take priority over writability. Units can be some trouble, and internal to a module you might want to not use them, but for public communication between modules (possibly written at different times or by different programmers) they extend the bug-preventing value of type-checking to physical dimensions and eliminate the need to remember what units other modules expect things in. This is only true when the data from the two modules are linked together directly. If you drop a value in a variant message to send it to a different loop the compiler can't verify the run-time type propogation is correct. In the hypothetical world where Labview ran the Mars Orbiter, using typed units may not have prevented the problem. There's more I wanted to comment on, but I'm falling asleep at the keybroddlxz.z.zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz... Quote Link to comment
drjdpowell Posted September 15, 2011 Report Share Posted September 15, 2011 Labels are one of those things that--in my experience--developers tend to change without thinking too much. Writing algorithms that unnecessarily depends on label text causes brittle code. Well, your already using generic message "names" that are text and can thus be misspelled; you'll need some mechanism to handle such issues, such as producing "unknown message" errors in the receiving code. The same error will be triggered the first time the code runs with a changed control label. New developers will quickly learn to use something called a "caption" instead of messing with the label. This is one area we differ. I'm more concerned with creating code that is sustainable rather than code that is easy to write. Often times these goals exert opposing forces on your design decisions. In fact, there is a noticable decrease in my code's sustainability when I try to make code that is "easy" to write. Readability, testability, extendability, etc., all take priority over writability. That brings up a question only you can answer: is LapDog intended to support and encourage a particular style of design, or is it to be of more widespread use to developers with differing styles? Personally, I would think having the control label match the name of the process variable controlled, with generic code connecting them, is an advantage for readability and testing, no? Note that using generic code for some controls doesn't preclude individual treatment of others (the "all controls" example I gave is just an example). This is only true when the data from the two modules are linked together directly. If you drop a value in a variant message to send it to a different loop the compiler can't verify the run-time type propogation is correct. In the hypothetical world where Labview ran the Mars Orbiter, using typed units may not have prevented the problem. Well, compile-time checking isn't possible at all in a messaging system, is it? If you send a U32 message to a loop expecting I32, or "BeginProces" to a loop expecting "BeginProcess", you'll learn about this error at runtime. Similarly for your "SetTemp" to 20psi message. BTW, it was the ground software, used to calculate how long to run the thrusters, that had the wrong-unit bug. The Mars Orbiter computer executed it's suicidal instructions flawlessly! -- James Quote Link to comment
jgcode Posted September 15, 2011 Report Share Posted September 15, 2011 Labels are one of those things that--in my experience--developers tend to change without thinking too much. Writing algorithms that unnecessarily depends on label text causes brittle code. FWIW, when I have to do this I like to use the following convention: If the Label is red (BD and FP), its dependent so don't go changing it. I think I copied it off someone after seeing it on LAVA (thanks to Olivier I think ) 2 Quote Link to comment
Daklu Posted September 16, 2011 Report Share Posted September 16, 2011 Well, your already using generic message "names" that are text and can thus be misspelled; you'll need some mechanism to handle such issues, such as producing "unknown message" errors in the receiving code. The same error will be triggered the first time the code runs with a changed control label. New developers will quickly learn to use something called a "caption" instead of messing with the label. I'm not saying using the control label as part of the message name is wrong. If that's a practice your development group standardizes on and everybody is comfortable with it then there's no problem. I'm just saying I don't like to use it for the reasons I stated. That brings up a question only you can answer: is LapDog intended to support and encourage a particular style of design, or is it to be of more widespread use to developers with differing styles? All the LapDog components (currently Messaging is the only released package, but Collections and Data Structures are around too) are intended to be usable by LVOOP developers regardless of their particular style. I don't provide everything needed to implement a given style, such as a Variant message, or a Command message, but they are very easy for developers to add on their own. Personally, I would think having the control label match the name of the process variable controlled, with generic code connecting them, is an advantage for readability and testing, no? Readability, probably yes. Testing, maybe. Flexibility, no. A lot of it depends on the project specifics, who the users are, and how much the user interface abstracts the implementation. If your software controls a system of valves and sensors and the operators are engineers who want direct control over everything, then yes, using control labels for message names might make sense. For higher level applications my fp events trigger "MyButtonClicked" messages. What that message actually does is handled elsewhere. Propogating fp control names down into functional code follows fairly naturally if you're using a top-down approach. In my experience the top-down approach leads to less flexible and tighter coupled code. Abstraction layers tend to leak. Using the bottom-up approach I name messages according to what makes sense in the context of that particular component, not based on what a higher level component is using it for. Well, compile-time checking isn't possible at all in a messaging system, is it? In theory it is, though I don't know how practical it would be. What breaks compile-time type checking is casting to a generic type--variants or a parent class, which is required to send multiple types over a single wire. If one were to create a messaging system where every data type sent had a unique queue for it then type checking would be maintained. The difficulty is in figuring out how to write the message receiving code without making a complete mess. Eliminating (or significantly reducing) run-time typecasting errors was my original goal of LapDog.Messaging. Creating a unique type (class) for each message and encoding the message name as part of the type eliminates a lot of the risk, though not all of it. Even though I've adopted a more generic approach with the current LDM release, users can still implement a "one message, one class" approach if they want. If the Label is red (BD and FP), its dependent so don't go changing it. That's a good idea. (As long as the control isn't on the UI.) Quote Link to comment
jgcode Posted September 16, 2011 Report Share Posted September 16, 2011 That's a good idea. (As long as the control isn't on the UI.) Ha, I was going to explicitly write that... But I don't think I have used that method on UI - and if I did, I would most likely send the data as e.g. a Class, and then update the UI accordingly using the 'API' of the UI I like to do this (with Class) if I have a group of data to send. Quote Link to comment
ShaunR Posted September 17, 2011 Report Share Posted September 17, 2011 (edited) That's a good idea. (As long as the control isn't on the UI.) You can still use it, but show the caption instead of the label. I use a similar method for changing languages. Captions are not used nearly as frequently as they should be (IMHO) Edited September 17, 2011 by ShaunR 1 Quote Link to comment
Daklu Posted September 18, 2011 Report Share Posted September 18, 2011 Uhh... Coloring the label red then showing the caption instead kind of defeats the purpose of coloring it red in the first place doesn't it? I agree with you regarding caption use, but I sure wish it were easier to switch back and forth between them. Maybe a hotkey combination that switches all fp controls between showing the label and showing the caption. Quote Link to comment
jgcode Posted September 18, 2011 Report Share Posted September 18, 2011 Uhh... Coloring the label red then showing the caption instead kind of defeats the purpose of coloring it red in the first place doesn't it? No - because the fact is you can change the caption without really thinking about it - but you haven't changed the label name which is the dependency (and hence your code is not broken)! The BD label will still be red, and this is only for the case of a UI VI. I love it! Quote Link to comment
drjdpowell Posted September 19, 2011 Report Share Posted September 19, 2011 I'm not saying using the control label as part of the message name is wrong. If that's a practice your development group standardizes on and everybody is comfortable with it then there's no problem. I'm just saying I don't like to use it for the reasons I stated. My development group of one is very good at standardizing. All the LapDog components (currently Messaging is the only released package, but Collections and Data Structures are around too) are intended to be usable by LVOOP developers regardless of their particular style. I don't provide everything needed to implement a given style, such as a Variant message, or a Command message, but they are very easy for developers to add on their own. The advantage of having a "VarMessage" as a standard part of the library is that you could add it to the enqueue polymorphic VI (in analogy to how you currently allow data-less messages), simplifying the wiring for those who use Variant messages. One can easily extend the polymorphic VI oneself, but then one has a customized LapDog library which makes upgrading to a new LapDog version trickier. Command Messages are different, I think, because they are inherently non-re-use (unless I'm mistaken, one would have a different tree of commands messages for each application). A VarMessage might also be an easier way in to LapDog messaging for those used to text-variant messages. Readability, probably yes. Testing, maybe. Flexibility, no. A lot of it depends on the project specifics, who the users are, and how much the user interface abstracts the implementation. If your software controls a system of valves and sensors and the operators are engineers who want direct control over everything, then yes, using control labels for message names might make sense. For higher level applications my fp events trigger "MyButtonClicked" messages. What that message actually does is handled elsewhere.Propogating fp control names down into functional code follows fairly naturally if you're using a top-down approach. In my experience the top-down approach leads to less flexible and tighter coupled code. Abstraction layers tend to leak. Using the bottom-up approach I name messages according to what makes sense in the context of that particular component, not based on what a higher level component is using it for. My experience is limited to much smaller projects than yours, and they are scientific instruments where one does need direct control of many things. And "abstraction layers" seem less attractive if your the only person on both sides of the layer. Also, I was more imagining a bottom-up approach, where the meaningful process variables are propagated up into the UI control labels. And one isn't constrained to do this; one has the flexibility to abstract things as needed. Currently, for example, I'm implementing control of a simple USB2000 spectrometer. I've written it as an active object that exposes process variables such as "IntegrationTime". In my simple test UI, I just dragged the process variables into the UI diagram, turned them to controls and wired them to send messages in the generic variants way I described in my examples. In the actual UI, which is a previously written program from a few years ago, the IntegrationTime message is sent programmatically based on other UI settings. Making a specific IntegrationTimeMessage class would have made writing the test UI much more work, without gaining me anything in the actual UI. BTW, you don't send "MyButtonClicked" messages, surely? Isn't that exactly the kind of UI-level concepts ("Button", "Clicked") you don't want propagating down into functional code? Eliminating (or significantly reducing) run-time typecasting errors was my original goal of LapDog.Messaging. Creating a unique type (class) for each message and encoding the message name as part of the type eliminates a lot of the risk, though not all of it. Even though I've adopted a more generic approach with the current LDM release, users can still implement a "one message, one class" approach if they want. I certainly see the advantages of the "one message, one class" approach. I'm just arguing for variants as a better generic approach over "one simple data-type, one class". -- James Quote Link to comment
Daklu Posted September 19, 2011 Report Share Posted September 19, 2011 Still short on time... quick response. (Some day I hope to go back and answer your previous questions.) BTW, you don't send "MyButtonClicked" messages, surely? Isn't that exactly the kind of UI-level concepts ("Button", "Clicked") you don't want propagating down into functional code? Correct. Here is a bd of the main ui in an app I am currently working on. This app uses a hierarchical messaging architecture I've described elsewhere. Each component has a mediator loop that handles all message routing between the external world (external to the component, not external to the app) and the various internal parts of the component. You can see the event structure for the LoadBtn control. It passes an "Inp:LoadBtnReleased" message to the mediator loop, which in turn passes a "GoToCenterPosition" message on to the application's business logic contained in the CoreSlave. There are two negative side effects of sending the Inp:LoadBtnReleased message down into the functional code: 1. If I want to change the way the user triggers moving the system to the center position, I have to change the name of the message through the entire app. It's not particularly difficult, but it is annoying and prone to errors. 2. More importantly, a "LoadBtnReleased" message doesn't have any meaning in the context of the CoreSlave or its subcomponents. They don't know anything about the UI. In fact, I can run the app without a UI at all if necessary. Suppose there were a need to automate a process normally done by users via the UI. I can drop the CoreSlave on a new bd, queue up a sequence of messages to execute the process, and let it run. Having a "LoadBtnReleased" message in that situation makes no sense and reduces readability. (Note: You'll notice this app doesn't use LapDog.Messaging. That was due to business reasons outside of my control. Instead I recreated the enqueue/dequeue functionality using traditional string/variant messages.) The advantage of having a "VarMessage" as a standard part of the library is that you could add it to the enqueue polymorphic VI (in analogy to how you currently allow data-less messages), simplifying the wiring for those who use Variant messages.... A VarMessage might also be an easier way in to LapDog messaging for those used to text-variant messages. I'll think about it. It goes against my instincts, but you have made valid points. One can easily extend the polymorphic VI oneself, but then one has a customized LapDog library which makes upgrading to a new LapDog version trickier. Rather than directly editing the LapDog.Messaging library, a better solution is to write your own wrapper class that provides the interface you want (polymorphic vis with variant support) and delgate the functionality to LapDog. That way minor version upgrades will be (mostly) painless. Command Messages are different, I think, because they are inherently non-re-use (unless I'm mistaken, one would have a different tree of commands messages for each application). In practice they probably usually are, but there's nothing about them that would prevent a well-constructed command message hierarchy from being reusable. To be honest I don't use them much--they tend to cause more coupling than I like. -Dave Quote Link to comment
drjdpowell Posted September 20, 2011 Report Share Posted September 20, 2011 Ah, I see, you have "internal to the UI component" messages in addition to messages such as "GoToCenterPosition" that are sent out of the component. Personally (illustrating alternate possible styles of programming that might use LapDog) I would probably try and write such a UI in a way that combines your top three loops in a single event-driven UI loop (using a User Event instead of a queue). This would eliminate "Inp:LoadBtnReleased" messages entirely. Your way is more flexible, I imagine, and allows the full use Queue functionality (so far, I'm happy with the limits of User Events). -- James BTW: is that a timed loop that reads a global variable? This is not your preferred architecture I would hazard to guess? Quote Link to comment
Daklu Posted September 20, 2011 Report Share Posted September 20, 2011 Personally (illustrating alternate possible styles of programming that might use LapDog) I would probably try and write such a UI in a way that combines your top three loops in a single event-driven UI loop (using a User Event instead of a queue). I used to do that too, but combining display updates with user inputs can easily cause subtle issues that may not become apparent until it's too late to fix easily. For example, what happens if a dialog box blocks the thread? No display updates are shown until the dialog box is cleared. What if nobody is around to clear it? The event queue will keep growing until eventually LV crashes with an out-of-memory error. Or maybe the dialog box is sitting there for 3 hours before somebody notices and clears it. Then they get to watch as the UI catches up with the last 3 hours of data updates. In general I have found that combining functionality--like so many things--is slightly faster to implement in the short term but costs way more time in the long run. BTW: is that a timed loop that reads a global variable? This is not your preferred architecture I would hazard to guess? Yep, it is. I prefer not to use globals, but sometimes business decisions override architectural decisions. Quote Link to comment
SteveChandler Posted September 20, 2011 Author Report Share Posted September 20, 2011 I don't want to change the subject since I am enjoying this very insightful debate. There are times when a global the perfect solution. I am sure most of you have seen this but for those who may not have. Modified version of this image from Broken Arrow. Quote Link to comment
drjdpowell Posted September 20, 2011 Report Share Posted September 20, 2011 Darn "delete" browser button ate my first post! My rewrite will be entirely different in focus because my initial post wasn't that interesting anyway. For example, what happens if a dialog box blocks the thread? No display updates are shown until the dialog box is cleared. Ah yes, the synchronous call to the unpredictable "User" process, I have been bitten by that before. I've written dialog boxes that beep loudly or that auto-cancel after a short while. I've toyed with the idea of making an asynchronous dialog box that works with command-pattern-style messages (since what is a dialog box but a way of sending a message and getting a response) but haven't put the effort in. Your multi-loop design is certainly robust against such issues, but how do you handle information that the UI Input loop might need? What if you have a dialog box that needs to be configured using your "DeltaZ" value, for example? My Users are always asking for dialog boxes that redisplay all the configuration controls for them so that can realize what they forgot to set. I don't see how your UI input loop could implement such a dialog. The event queue will keep growing until eventually LV crashes with an out-of-mem... Just as an aside, has anyone heard of a design for a message-passing system where messages are flagged by what should be done if they are undeliverable for a significant time? Most of my messages convey current state information, and are rendered obsolete in a few seconds when the next message of that type arrives. Having the queue fill up with obsolete messages and crash the program seems silly. The ideal queueing system would know this and only save the last version for most messages. One could use a size-limited lossy queue, but unfortunately some messages are of the type that must be delivered. -- James Quote Link to comment
Daklu Posted September 30, 2011 Report Share Posted September 30, 2011 Ah yes, the synchronous call to the unpredictable "User" process, I have been bitten by that before. I've written dialog boxes that beep loudly or that auto-cancel after a short while. Never done the beeping bit, but I have done auto-cancelling dialog boxes. Problem is determining a time everyone can agree is appropriate. They want the wait time to be short when they're not interested in it and long when they might be distracted by something else but still want to interact with the app. Users... *sigh* I've toyed with the idea of making an asynchronous dialog box that works with command-pattern-style messages (since what is a dialog box but a way of sending a message and getting a response) but haven't put the effort in. Been down that road. It certainly works, but unless you want to create a unique loop for every dialog box (not very scalable at all) you're pushed into calling the vi dynamically and dealing with those associated headaches. I find it easier to save dynamic calls for those situations when they're really necessary. Your multi-loop design is certainly robust against such issues, but how do you handle information that the UI Input loop might need? That's a good question. All loops need to be able to receive messages, at the very least so they can receive an 'Exit' message. For loops with an event structure I create a user event of the generic message type and put a message handling case in the user event handler. (The screen shot shows a generic "DisplayPrompt" message handler I created earlier that I am in the process of refactoring away to improve readability.) Some people like to use user events as a general messaging construct, but I prefer queues due to their flexibility, transparency, and robustness. The only time I use user events is for sending messages to user input loops. What if you have a dialog box that needs to be configured using your "DeltaZ" value, for example? My Users are always asking for dialog boxes that redisplay all the configuration controls for them so that can realize what they forgot to set. I don't see how your UI input loop could implement such a dialog. The data that is displayed in DeltaZ comes from the Core and is routed through the mediator loop. If the UI loop need to know DeltaZ as well then I can either copy the data in the mediator loop and send it to both the display and UI loops or store the data with the mediator loop and send it to the display loop with the command to display the dialog box. The exact implementation I use depends on the specifics of the application. (Why do they want a new dialog box for validating their inputs? Seems like it would be easier to color controls red if the input is invalid, refuse to let them progess until valid inputs are entered, or something like that.) Most of my messages convey current state information, and are rendered obsolete in a few seconds when the next message of that type arrives. Having the queue fill up with obsolete messages and crash the program seems silly. The ideal queueing system would know this and only save the last version for most messages. I respectfully disagree. The ideal queueing system does exactly what the current queue implementation does. It spits things out in the order it received them with very little overhead while providing users with the ability to add on additional functionality if they want to. What you're asking for adds overhead to the queue functions. To the best of my knowledge Enqueue and Dequeue are O(1) operations. Saving only the last version of each message will turn at least one of them (probably Dequeue) into an O(n) operation as it has to iterate through the entire queue to check for duplicates. As a developer, I can make a decision to wrap NI's low level functions in sub vis to add functionality in exchange for requiring more execution cycles, more memory, etc. I don't have any way to remove functionality from those functions to make them perform faster if that's what I need. I generally oppose the Idea Exchange posts that ask for new features or options on the low level functions for this exact reason. Convenience always comes with a cost. I will say that over the years I've seen several requests for this kind of feature. I have run into the same kinds of issues you have and at one time wished for the same thing. However, I humbly suggest that the problem may not be a lack of functionality in queues, but is instead the result of the programming patterns you are using. Specifically, I believe the need for this kind of queue functionality comes about from indiscriminantly using QSMs and insufficient planning. (Though I have nothing other than my own anicdotal evidence to support the theory.) You mentioned a state message is rendered obsolete in a few seconds and would like the old message replaced in the queue by the new message. If I may ask a pointed question, why do allow messages--which should be propogated immediately through the application--to sit around in the queue for several seconds unprocessed? What can you do to improve your application's response time to messages? When I asked myself those (and other) questions I ended up with the hierarchical messaging architecture. Creating more complex queue functionality may be a workable solution, but I have to say that since I've started using hierarchical messaging the need for complex queue functionality has disappeared. In fact, even though I created a priority queue for LapDog, I've found my messages are processed fast enough that I don't ever need it. -Dave Quote Link to comment
drjdpowell Posted September 30, 2011 Report Share Posted September 30, 2011 I respectfully disagree... I agree! In fact, I started to immediately think of "Priority Queues" as an example of a queue extension that didn't seem that useful to me. The design should be such that messages are handled promptly. In fact, I've never seen much advantage in "Preview" or "Flushing" of the queue. That's one of the reasons that my own messaging system abstracts Queues, User Events and the like as "Messengers"; I'm happy to ignore the extra features of Queues over User Events. I was thinking about an eventual design of a "Network Messenger" when wrote my previous post, and distributed computing where the network may have temporary disruptions. Or a computer may have to reboot or something. It was in that context that I was interested in what happens to queued messages building up. I certainly don't want to add extra bells and whistles to the raw queue primitives. Been down that road. It certainly works, but unless you want to create a unique loop for every dialog box (not very scalable at all) you're pushed into calling the vi dynamically and dealing with those associated headaches. I find it easier to save dynamic calls for those situations when they're really necessary. I've been trying a different tactic of standardizing the dynamic call, with the launching of all VI's being identical and accomplished with the same "Launch" subVI. Every dynamic VI sits behind a "Messenger" and receives "Messages". Thus I have to only deal with the complexity once. I think I can easily add async dialog boxes to this design without ever having to revisit the details of dynamic launching. (Why do they want a new dialog box for validating their inputs? Seems like it would be easier to color controls red if the input is invalid, refuse to let them progess until valid inputs are entered, or something like that.) The inputs are "valid", they just forget to change them from the default, or change them and forget to change them back. -- James Quote Link to comment
SteveChandler Posted September 30, 2011 Author Report Share Posted September 30, 2011 The only time I use user events is for sending messages to user input loops. -Dave I have done this before. The familiar but unlabled blue wire is my mediator loop. Quote Link to comment
Daklu Posted September 30, 2011 Report Share Posted September 30, 2011 I was thinking about an eventual design of a "Network Messenger" when wrote my previous post, and distributed computing where the network may have temporary disruptions. Or a computer may have to reboot or something. Wow, now you're getting into the realm of large messaging middleware system companies charge through the nose for. It would be interesting to work on something like that but it's way outside anything I've ever been asked to do in Labview. I've been trying a different tactic of standardizing the dynamic call, with the launching of all VI's being identical and accomplished with the same "Launch" subVI. I've written abstract DialogBox classes before where each unique dialog box is a separate child class. Giving the parent class a static Launch method ought to work, though I don't remember if I've specifically tried it. Every dynamic VI sits behind a "Messenger" and receives "Messages". Thus I have to only deal with the complexity once. Actually I was thinking about debugging and maintenance more than writing the code to launch the vi. Personally I find it a pain to debug code when dynamically launched vis are used. I have done this before. The familiar but unlabled blue wire is my mediator loop. That's exactly what I do when using LapDog.Messaging. (At least the technique is the same. Updating front panel controls may or may not occur in the user input loop.) Quote Link to comment
drjdpowell Posted October 1, 2011 Report Share Posted October 1, 2011 Wow, now you're getting into the realm of large messaging middleware system companies charge through the nose for. It would be interesting to work on something like that but it's way outside anything I've ever been asked to do in Labview. I don't need it that complex, but I was looking into using one of the Open Source (ie free) middleware messaging systems such as RabbitMQ or ZeroMQ. Why reinvent the wheel? Unfortunately, there are no LabVIEW wrappers and I don't have the skills to create them (anyone have any experience with using these from LabVIEW?). Instead, I'm thinking of just doing a simple Messenger using the TCP primitives. -- James Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.