Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 09/03/2013 in all areas

  1. I don't think it takes too long after deciding to do an actor based project to run into the case where you have an actor spun off without a way to kill it. You'll figure that out and get your solution working so you can pass it off to someone else and forget about it. Soon after, that someone else will come to you and say something like "yeah, those actors are cool and all, but they're really hard to debug" I ran into some of these problems a while ago, so I decided to write a little tool to help with it. I decided to call it a monitored actor. Here were my design criteria: I want a visual representation of when a monitored actor is spun up, and when it is shut down. From the visual representation, I want to be able to: stop actor, open their actor cores, and see if they're answering messages The visual representation should give you an idea of nested actor relationships. Implementing a monitored actor should be identical to implementing a regular actor. (meaning no must overrides or special knowledge) Monitored actors behave identically to Actors in the runtime environment. It turns out that you can pretty much accomplish this by creating a child actor class, which I've called Monitored Actor. A monitored actor's Pre-launch Init will try to make sure that the actor monitor window is made aware of the spawned actor, and Stop core will notify it that the actor is now dead. The actor monitor window contains ways to message the actors and pop up their cores and such. I think it's fairly obvious what each button does except pinging. Pinging will send a message to the actor and time how long it takes to get a response. This can be used to see if your actor is locked up. The time it takes to respond will be shown in the ping status column. if you want to periodically ping all the actors, set the "poll Frequency" to something greater than 10ms. This will spawn a process that just sends ping messages every X ms. Where I didn't quite meet my criteria: If you were to spawn a new actor and Immediately (in pre-launch init) spam it with High priority messages, the Actor monitor window will not know about the spawned actor until it's worked through all the High priority messages that got their first. You probably shouldn't be doing this anyways, so don't. Download it. Drop the LVLIB into your project. Change your actor's inheritance hierarchy to inherit from monitored actor instead of actor. You shouldn't have to change any of your actor's code. The monitored window will pop up when an actor is launched, and kill it's self when all actors are dead. Final note: This was something I put together for my teams use. It's been working well and fairly bug free for the past few months. It wasn't something I planned on widely distributing. A co-worker went to NI week though and he said that in every presentation where actors were mentioned, someone brought up something about they being hard to debug or hard to get into the actual running actor core instance. So I decided to post this tool here to get some feedback. Maybe find some bugs, and get a nice tool to help spread the actor gospel. Let me know what you think. Monitored Actor.zip
    1 point
  2. Yeah, well, no system is perfect. Just to be clear, the point wasn't to be a snob and say "I only want CLAs here". The point was to say "you have to be this tall to go on the ride", meaning have at least a basic understanding of LV. The questions wouldn't require a brain the size of a planet to answer.
    1 point
  3. Ah, the "double dispatch to compare heterogenous types" problem. An ancient frustration of software developers everywhere. And, worse, I suppose you want the comparison operation to be commutative too (i.e., it doesn't matter which object you put into the top input and which into the bottom input)? a) read this: http://en.wikipedia.org/wiki/Double_dispatchhttp://en.wikipedia.org/wiki/Double_dispatch b) I have never heard of a good solution to this problem in any computer language, but LabVIEW is worse than most because of some limitations on our features -- such as the inability to type cast a VI refnum into any connector pane type *without* LabVIEW type checking it. That kind of "reckless type casting" is a damn fine way to crash any application, but if you can write a system that guarantees (and I mean system-level provable) that all the casts are safe, that's the key to a high performance, low maintenance implementation of such a comparison algorithm. But LabVIEW doesn't generally include "use at your own risk" nodes (the exceptions being Type Cast and Call Library, but even Type Cast has some restrictions which is why it doesn't work for this use case). Even if you had such reckless type casting for VI refnums, this is a hard problem to solve elegantly. I generally recommend that you do the type testing, and either have your own static dispatching through a multilayer maze of case structures or build a 2D dynamic dispatch table of your own. This has an obvious performance hit, even if you implement your own "Get Class Index.vi" that every class overrides to return a unique (but compact sequential over the whole set) integer. There is only pain and suffering down this road if you want to avoid runtime type checking. But it is possible. There are multiple ways to do it. All of them are bad in some way. The Visitor pattern is one you will become very familiar with if you try to do this... lots of variations on the Visitor pattern that all essentially go like this: You create a comparison object that visits the first object to be compared, collects some data then visits the second object and actually does the comparison. You can find endless variations online discussing this problem. One solution that does NOT involve the Visitor pattern is this one... If you know the total set of child classes that will ever exist, this works with high performance but high maintenance burden and lots of VIs: 1. In the ancestor class, create a method "Is Valid.vi" that is dynamic dispatch on the top input. 2. In the ancestor class, create N methods named "Is Valid Assuming First Input is <class name>.vi" where <class name> is the name of a child class. The top input is the child class type. The bottom input is the ancestor type and is dynamic dispatch. Do this for every child class that is not an abstract class. 3. Each child overrides "Is Valid.vi" and uses that VI to wrap a call to "Is Valid Assuming First Input is <class name>.vi", where <class name> is this child class' name. 4. Each child overrides ALL of the methods for "Is Valid Assuming First Input Is <class name>.vi" so that it's type is the bottom type and the other class is the top type. Here you write the actual comparison between these two objects because you now know the exact data type. Oh, but there's a problem... you don't have access to the private data of the other class. So you expose the necessary data accessors to dig into the other class. And you write the comparison. 5. But THEN you take that comparison and you do "Create SubVI From Selection" because you need that exact same comparison in the function on the other class where the top and bottom inputs are flipped. -- end -- This results in a system that is actually quite fast at runtime but is a pain to maintain -- the number of methods in the system expands *geometrically* with the number of concrete child classes. All of this gets even worse if you want to have plug-ins or dynamically loaded classes (the difference being with dynamically loaded classes, you know all the classes ahead of time but you don't want them in memory whereas with plug-ins you don't know the complete set when you write the framework). So far as I know, there is no elegant solution to this problem anywhere in CS. If you find one, please let the world know.
    1 point
  4. I tried it through .net and it works. I had to browse for the mscorlib.dll file for LabVIEW to find the SHA256Managed-class. Cheers, Mikael
    1 point
×
×
  • Create New...

Important Information

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