-
Posts
1,994 -
Joined
-
Last visited
-
Days Won
183
Content Type
Profiles
Forums
Downloads
Gallery
Everything posted by drjdpowell
-
Self-addressed stamped envelopes
drjdpowell replied to drjdpowell's topic in Application Design & Architecture
Synchronous ONLY is perhaps not a good idea, but synchronous messaging is good for synchronizing things. As an example, suppose I had a spectrometer and a sample handler for deploying samples to be measured. I might want to deploy a calibration sample, THEN calibrate the spectrometer, THEN deploy a sample to be measured, and THEN measure the spectrum of the sample. This would be trivially easy to do with four synchronous queries chained together by their error terminals. If either spectrometer or sample handler had a problem it would return an error message as its reply (such error appear on the error-out terminal of the Query VI). Of course, if either component needs to signal something immediately there needs to be a dedicated channel. In which case, neither my synchronous nor asynchronous "reply" examples work, since in both cases the communication channel is a part of the received message. I've been developing a third communication mode as part of a "Active Object" template: registering for event updates (the OOP "Observer Pattern") that would work for this. All three modes should be useful and can be used on the same active object. -- James -
Self-addressed stamped envelopes
drjdpowell replied to drjdpowell's topic in Application Design & Architecture
For completeness, here a simple example of an asynchronous query, where the controller has its own incoming messenger, which it attaches to its outgoing message to Process A, allowing it to receive the reply asynchronously: This example also shows a User-Event-based Messenger. -- James -
Self-addressed stamped envelopes
drjdpowell replied to drjdpowell's topic in Application Design & Architecture
I agree, and I've been trying to design my messaging system in that way, so that one can use it for simple things without having to understand everything that might be done with it. My original design goal was to be able to have processes that send messages without having to know whether the messages are being sent by queue, or notifier, or user event, or UDP or TCP. And for processes that receive messages to be able to transparently use network communication (TCP etc.) in place of local communication. That makes things simpler, not more complicated. And my initial goal for the Parallel Processes is to have a simple template for creating "speak-only-when-spoken-to" simple active objects that can be "queried" by higher-level processes. Thus the synchronous, command-reply communication (shown below with text-varient messages) was the first thing I developed (which lead to the idea of having each message carry it's own reply method): I find this synchronous communication to be more clear and simple to use than asynchronous. I probably shouldn't have first introduced my messaging design with the complex example of my first post, as one would start out (and perhaps end) with much simpler uses. Getting back to the more complex example of my first post, although the messaging is direct from A to B, all the routing and slave interactions are setup by the main VI. In my system, one can look at the creator of the process to see who is passed the wire representing the ability to communicate with that process (hopefully, there are only a limited number of such potential message senders). And I'm hoping my "Message Logger" can be developed into a useful debugging tool. Below, I've modified the Logger to add some tracing information (the call chain of the process sending the message and the message timestamp). -- James -
Self-addressed stamped envelopes
drjdpowell replied to drjdpowell's topic in Application Design & Architecture
Yes, I nearly titled this conversation "Yet another messaging system". Looking at your "MessagePump" loop, I can see the great similarity, just with different terminology. My "MSG" message class contains a label (your "message identifier") and a "Send" object (your "Callback"); children of MSG add "Data" (your "parameters") of various kinds (the example I gave used a text-data message). "Send" is a virtual class, who's central method, "Send.vi", does nothing, but it's various children override Send.vi with different communication methods or other functionality. So far, I have Queue and User-Event "Messengers" (hopefully to be extended in future to a network-enabled TCP messenger); "Parallel Process", an active-object design that uses the messengers for communication; and "ObserverSet", an extension of Send intended for allowing multiple processes to receive ("observe") the same message. Here's an extension of my first example, where I've added a Message Logger (Parallel Process) that "observes" the messages to both processes A and B: Note that I made no changes to A, B or the Controller Loop; none of these processes are aware of the existence of the Message Logger. I've been experimenting with what kind of interesting functionality I can build into the Messaging system itself, while using only quite simple processes to message between. Here's a further modification of to example where I replace the "Controller" Loop with a "Metronome" parallel process that sends "MetronomeTick" messages periodically to the ObserverSet registered with it. I've used the ability of Observers to substitute an alternate message to have Metronome send the "SendTimeString" message to process A. Note that A, B and Metronome know practically nothing about each other. They don't use any compatible message labels and they don't know what underlying communication method they are using. Metronome needs to "send" updates to its ObserverSet, but doesn't know anything about the number or nature of observers, or that it's messages are being rewritten. I had originally started writing a parallel process that maintained arrays of registered observers, with arrays of alternate message labels, but realized that all this functionality could be built into a extension of the "Send" messaging class, and thus added for free to any (much simpler) process that can register one "Send" object for updates. In a hierarchal master-slave tree structure, like Daklu suggested, there is less potential for circular dependancies, as any synchronous messaging would always be from master to slave. And, of course, one needs a timeout error; here's my synchronous "query": -- James -
Hello,The recent posts about "Message Routing" has inspired me to mention a variation on this idea. In particular, I am thinking of Daklu's description of his "Slave Loops" that only communicate with their masters (requiring the master to "mediate" communication between slaves), and Mark Balla's Message Routing Architecture. I have been working on my own LVOOP Messaging system, one in which there aren't specified "output" channels; instead, each message can contain the method to rely or respond to it. Sort of a self-addressed, stamped envelope. This allows one to build a "hierarchical tree of master/slave loops" as Daklu suggests, but with the ability to direct messages to thier final recipient without mediation. A simple example: In this example, the Controller (master) sends a message to Process A (label="SendTimeString") with the attached reply address (command queue) of Process B, along with an alternate label, "CurrentTime", to be used for the reply message. Thus, Process A directly sends a message to Process B, with no mediating or routing processes in between, yet without either process knowing anything at all about each other (they don'y even use the same message labels). The Controller sets up the communication link between A and B, but doesn't itself need to handle the message. One can extend this into an "Observer pattern", where the Controller registers Process B as an observer of Process A's regularly occurring "TimeString" events, (complete with message relabeling to "CurrentTime"), again with neither A nor B having to know anything about each other. -- James
-
Object-Based State Machine Pattern
drjdpowell replied to Daklu's topic in Application Design & Architecture
I don't think you give that impression. It's not even close to complete (the four-hour time limit would be a killer), but I can show the statemachine with a case that is; the "Main Menu" when the user selects the "Fast Cash $50" option (see attachment). I found the ATM problem to be obviously calling for a state machine; it practically defines all the states for you. The problem equally seems to call for some LVOOP, again practically defining all the classes: "User Console" and "Account Database", with children "Simulated Console" and "Simulated Database" (ready for the eventual replacement with "Physical Console" and "Enterprise Database"). If I were to use a JKI-SM (though I wouldn't be allowed the template on the exam), I might instead have had "Macros" such as... "// Main Menu Card Slot >> disable Keypad >> disable Menu State >> Main Display Message >> Main Menu Wait for User Input Process Main Menu Input" ... with the "Process Main Menu Input" calling (if the User pushed this button) "Fast Cash $50", which would call "Withdrawal >> Complete". The QSM version would not be terrible but would be clearly poorer than a true SM. But this problem is very clearly definable as a statemachine. Most programs I write involve "do the task requested before returning to idle", with the complexity of the task being more easily broken down into sub-tasks than states. For complex tasks, JKI-style macros are quite clear and they're quick to write compared to wiring up subVIs. The subVI option is clearer than JKI-SM frames, and I can appreciate some of the other advantages you point out, but the real reasons I've started to use subVI's more and more lately is the advantages of OOP classes and dynamic dispatch. BTW, what do you think of the provided example solution to the ATM example test? The one where it's done with Action Engines. -- James -
Object-Based State Machine Pattern
drjdpowell replied to Daklu's topic in Application Design & Architecture
Sorry, should have used a smilie of some kind. Not an effective smilie user. There. On a side note, I have just learned that there is a practice CLA exam and tried a go of it last night. Being an ATM program with obvious state-fullness I used a state machine, my first real one ever, I think! -- James -
Object-Based State Machine Pattern
drjdpowell replied to Daklu's topic in Application Design & Architecture
Hi Daklu, Another of the problems with the bad "QSM" name is that there are many conversations where someone brings up "QSM" and it triggers comment about their flaws as true state machines, "state diagrams" and such, WITHOUT ascertaining if the original use of the QSM pattern was anything to do with "different responses to the same message depending its current state". I suspect most use (and certainly better use) is more similar to what you use your message handler for. It may even be intended (dare I say it) as a structure for programing without separating the UI from the rest of the code! We lesser programmers tend to do that. So I did get the mistaken impression that people were suggesting true state machines for all sorts of purposes that seemed to me to be a poor fit. You might be right. I think (lest I'm mistaken) that a QSM like JKI's is interchangeable with a QMH with appropriate subVIs (and the JKI-SM can meet your three conditions for QMHs). In my own use of the JKI-SM, my first uses definitely were flawed by too little use of subVI's, while lately I use a mix of mostly subVIs for low-level operations and frames of the case structure for higher-level ones. Your argument that case structures, loops and subVI's is clearer than a queue for complex processes is a much better one than your state-machine related criticisms; now your talking about what people use "QSMs" for. -- James -
Different enum strings for each row in array
drjdpowell replied to MartinMcD's topic in User Interface
You could also consider using a multi-column listbox and right-click menu, customizing the menu to the set of options available for the specific box right-clicked on, then write the selected option into the box. -
Object-Based State Machine Pattern
drjdpowell replied to Daklu's topic in Application Design & Architecture
Hi Daklu, Most of your criticism of the (badly named) "QSM" is all down to the flawed design of using the same queue for messages to the QSM and "states" (really operations) within the QSM. This flaw may be common, but it is not inherent to QSMs, and templates such as the "JKI statemachine" don't have it. There is no asynchronicity in a properly designed QSM (your point 4), nor do producer loops directly initiate QSM "states" (point 1). As to better separation of the UI (point 3), I'm not sure ignoring messages is all that great an idea (I have visions of the annoyance my Users will have after pressing "start", and coming back 5 hours later to find the equipment just sitting there). Point 2 is complicated since a QSM isn't actually a state machine and thus isn't a good way to implement a complex state diagram. But how good is a true state machine at implementing a complex flow chart? Aren't you making the same error as "QSM for everything" people by suggesting "true state machine for everything"? Is a hammer a useless tool just because people have mislabeled it as a type of saw? -- James -
Macro State in State Machine
drjdpowell replied to dannyt's topic in Application Design & Architecture
The flowchart tends to seem more intuitive to me for what I'm doing, so the badly-named QSM is good for me. Admittedly, this may be just a lack, on my part, of a clear understanding of the value of state diagrams. -- James -
Only thoughts: -- I would separate the changing of frames of reference (AB in A-frame --> AB in B-frame) from the inverting of the vector (since the later is then trivial) -- shouldn't the change of reference frame involve two relative angles? rather that the single angle your code snippet seems to have? -- James
-
Macro State in State Machine
drjdpowell replied to dannyt's topic in Application Design & Architecture
That is a flawed design, due to the use of the same queue for both internal operations of the lower loop and incoming messages from the event structure in the upper loop, leading to indeterminacy in the order of operations. Good design always uses separate queues. I, personally, would recommend anyone starting to use "QSMs" (how about "Queued Operation Machines", QOM?) to use a good template such as the JKI statemachine toolkit to avoid these types of design mistakes (which I sadly recall making myself). -- James -
Macro State in State Machine
drjdpowell replied to dannyt's topic in Application Design & Architecture
For the benefit of Dannyt and others reading, "Queued State Machines" such as the JKI state machine are misnamed in that they are not actually state machines. True state machines are a different concept, and are what Paul_at_Lowell and Daklu are talking about. QSMs are more like queued command or queued operation machines, and thus the concept of a "macro" set of commands applies. -- James
