Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 03/13/2014 in all areas

  1. When developing apps with multiple parallel processes, many developers prefer messaging systems over reference-based data. One of the difficulties in messaging applications is how to handle request-reply sequences between two loops. Broadly speaking there are two approaches: synchronous messages and asynchronous messages. In some ways synchronous messaging is easier to understand. The sender asks the receiver for a piece of data and waits for a response before continuing. The downside is the sender isn't processing new messages while its waiting. Important messages will go unnoticed until the sender receives the data or gets tired of waiting. It can also be hard to verify correctness in synchronous messaging system. Cross loop execution dependency may hide deadlocks in your code and they are very hard to identify. Asynchronous messaging sidesteps the issue of deadlocks. Each loop executes on its own schedule so there's no danger of multiple loops waiting on each other. The drawback? There are a lot more messages to handle and the bookkeeping for sequences of data exchanges can get messy. For example, if a data consumer, C, needs data from a data producer, P, it might send a GetData message then continue servicing messages as they arrive. When P processes the GetData message, it in turn sends a HereIsData message back to C. C then not only needs to implement a HereIsData message handler, but also needs to keep track of the reason why it wanted the data in the first place so it can continue its previous task--there is more state to manage. Since synchronous messaging processes the returned data inline with the request it doesn't have this problem. Often I eliminate the need for additional state management by having P broadcast new data to all C's every time it changes. That ensures each C has the latest data and can use its internal copy inline instead of requesting it and waiting for a response. Sometimes that is not a very good solution. Consider the case of a high output P and a C that sometimes, but rarely, needs the data. That's exactly what I ran into recently with a motion control system where the motor positions are updated every 10 ms or so but the UI needs to know position data maybe 5 times every 30 minutes. Continuously broadcasting position data to the UI seemed like a waste of resources. Where am I going with all this? A little while ago I ran across a concept called "futures." It is essentially a promise to supply needed data at some point in the future when it is not available at that instant. The future doesn't have the data now, but it will when it is redeemed. Rather than broadcasting thousands of unnecessary messages or creating lots of extra states to manage, I used futures to get the readability of synchronous messaging while (mostly) maintaining the natural parallelism of asynchronous messaging. I don't have time to code up an example right now so let me try to describe it. (If there's interest I'll try to post an example later.) The process flow I used for my futures is similar to this: 1. UI determines it needs position data from the motion controller (MC.) 2. UI creates a future and keeps one copy for itself, sending the other copy to the MC as asynchronous message data. 3. UI continues processing, not caring about the specific data right now but trusting it will be there when needed. 4. MC eventually processes the message and "fills" the future. 5. UI gets to the point in its execution where it needs the data, so it "redeems" its copy of the future and obtains the data filled by MC. Compare that with synchronous messaging and the difference becomes clear: 1. UI determines it needs position data from the motion controller (MC.) 2. UI requests position data from MC. 3. UI sleeps while waiting for a response. 4. MC eventually process the message and sends a response. 5. UI continues processing, confident it has the data it needs for future processing. I don't claim this idea as my own, or even that its new. I implemented the future using a notifier. In fact, under the hood a future looks a lot like a synchronous message. The important difference is where the waiting takes place. Synchronous messaging forces the sender to wait for a response to the message before continuing. Futures give the sender more control over their own execution. They can redeem the future immediately and behave like a synchronous message or they can redeem it in the future and continue doing other stuff. It turns out I unknowingly implemented futures about a year ago as a way to have synchronous messaging with LapDog. At the time I was focused on obtaining the response before continuing, so it never occurred to me to defer reading the notifier until the data was actually used. I've just started using this idea so I don't really know where it'll lead. I don't think it's a "safe" replacement to synchronous messaging; there is still the danger of deadlocks if futures are used extensively. I think they're better used as a lightweight request-response mechanism when implementing a new state is too heavy and broadcasting is too resource intensive.
    1 point
  2. So like many other developers I have my own spin on the actor design. Had yours been developed when I needed it I may have used it instead but that's besides the point. With my actor implementation I have a actor dedicated to probing the other actors messages. This can be opened by going to Help >> Debug Application >> Actor Probe from the application so it can debug messaging in an EXE. I have a few things I'd like to suggest that you can choose to do or not. In my probe I have the option to allow the size of the history to be changeable. It's not necessary but some times having too large a history can add unneeded extra memory but at the same time when debugging you want it to be larger. I also added a Pause and Resume function because some times messages come in quickly and with a history size being limited I might want to pause and look at what happened while the application continues as normal. Lastly I'd recommend some way to look at the actual data that is being sent. I see you have something for this but for more complicated data structures I don't think you'll see the values. I highly recommend the Variant Probe. With this not only can I see the history of messages sent, I can also look at the actual data that is being sent with it. All of these things combined have helped me troubeshoot multiple applications when deployed and behavior can be slightly different then in a development environment. I do think having a DT between messages is a great idea and I may implement that in the future.
    1 point
  3. Thanks jcarmody! I have a suggested improvement. I was annoyed by the fact that once I changed the VI to run-when-opened, I could no longer edit the VI - I wanted to edit the VI description. I had to re-download. To make the VI editable, I modified it to use the variable (which you already had in place! nice!) Close Panel on Exit. This starts out False but becomes True in Idle subcases 1, 2, and 3, i.e. if the user does anything. So if the user doesn't do anything and the VI exits on account of being the only one running, then the front panel stays open. And then you can edit it. I put this at the end of the VI description: "To edit this VI, stop all other VIs first before using this one."
    1 point
  4. I came across this thread: http://lavag.org/top...qr-code-or-not/ and decided to dust off my old QR code generator, clean it up and see if it would be useful. I had no access to the formal spec-sheet, my info came from a combination of wikipedia, textbooks on Golais fields (fun stuff), and a lot of reverse engineering. As I remember things I am trying to actually document the code this time around. QR Generator_v2.llb
    1 point
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.