Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

How does AF handle continuous execution of some action?

Solved!
Go to solution

Daklu wrote:

In principle there is nothing wrong with having a loop send a message to itself.  In practice, based on the code I have seen over the years, it is very easy to introduce subtle race conditions that may not be apparent or discovered until it's too late.  QSMs often use "states" where sub vis are more appropriate.  That's what makes them dangerous.  The "states" must execute in a specific order.  If the expected sequence is disrupted unpredictable things happen.  Usually that's bad.  Sending messages to self makes it easy to introduce unintentional sequential requirements that can't be enforced.

An advantage of the Actor Framework and similar things is that one is forced to delegate the actual work of a message to subVI methods of the Actor object.  Thus, it is actually quite easy to keep the messages themselves atomic.  If one wants methods X, Y, and Z to execute in sequence, it's easy to create a "DoXYZ" message that calls the methods in order without possibility of interference.  Of course, one still needs to be wary of sending "DoX", "DoY", and "DoZ" sets of messages.  But at least it is always easy to create an atomic message, because one has already put all your actual non-atomic operations in subVIs.  This is an improvement over many traditional QSM designs.

-- James

0 Kudos
Message 21 of 34
(1,604 Views)

There are two methods to invoke an operation atomic within the Actor Framework:

  1. Batch Message
  2. Wrapping Multiple Method Calls and creating a message for the "wrapper" (as mentioned by James)
CLA, CTA
0 Kudos
Message 22 of 34
(1,604 Views)

GotRobotFriends wrote:

I want control to continue a time-critical sense. I can't afford to have the actual control broken up by whatever requests the actor is receiving from its caller.

Accessing the class via a DVR will block execution in your parallel process.

If the only requests for the process Actor are control related, then you will not have this problem.  You could have a "Manager" and a "Process" Actor.  The manager would service requests and handle messages from the outside world.  Nobody but the Manager could message the "Process".  The "Process" could send messages (asynchronously) to the Manager with state updates.

There is a Timed Loop Actor within one of the 2012 Actor Framework examples.  I would suggest inheriting from this for your continuous process.  In your process actor, you could track the loop rate using a shift register in your class methods or storing timing information in the class private data.

CLA, CTA
0 Kudos
Message 23 of 34
(1,604 Views)

I don't have LV 2012. Also, Actor Core.VI must apparently make an unconditional call to its parent method (I hit this problem trying to write a TCP actor). That being the case, what's the point of creating a manager and process actor (in my head it looks just like the parallel loop case, except that the message handler is the "manager" and the "process" is implemented with a 0 timeout on its actor's queue, and it's even harder to follow execution and pass data).

Incidentally, how do you even implement a 0 timeout on the actors queue, wouldn't that require diving into that parent actor method, in which case, all your actors will then be 0 timeout?

As an aside, is it possible to call an over-ride of Actor Core.VI which doesnt make a call to its parent VI?

0 Kudos
Message 24 of 34
(1,604 Views)

I don't have LV 2012.

If you were not a member of the LabVIEW 2012 beta, it should be available soon.  A new version is usually released the first week of August.

GotRobotFriends wrote:

Actor Core.VI must apparently make an unconditional call to its parent method (I hit this problem trying to write a TCP actor).

As an aside, is it possible to call an over-ride of Actor Core.VI which doesnt make a call to its parent VI?

Actor Core.vi is the QDSM that the framework hinges on.  You must call this and should not modify its behavior (besides adding debug code).

Incidentally, how do you even implement a 0 timeout on the actors queue, wouldn't that require diving into that parent actor method, in which case, all your actors will then be 0 timeout?

As an aside, is it possible to call an over-ride of Actor Core.VI which doesnt make a call to its parent VI?

As mentioned in this thread, there is no timeout on the Actor's queue.  The time-delayed send message should be used to execute a method every "n" seconds.

...what's the point of creating a manager and process actor (in my head it looks just like the parallel loop case, except that the message handler is the "manager" and the "process" is implemented with a 0 timeout on its actor's queue, and it's even harder to follow execution and pass data).

GotRobotFriends wrote:

I want control to continue a time-critical sense. I can't afford to have the actual control broken up by whatever requests the actor is receiving from its caller.

1. Why create the Manager Actor?

You mentioned that you did not want anything to "block" the continuous process with requests.  The manager would handle requests while the process is left to do its work.  This approach is better than using a DVR.

2. How is this different than the parallel loop case?

  • It is extensible.  You could launch multiple process from the manager copy/pasting loops.
  • It does not require "blocking" of a DVR.  If it took 30 seconds to access some data from within the DVR, your parallel loop process would pause for 30 seconds.
  • You don't have the risk of deadlocks as with DVRs.

3. It's even harder to follow execution and pass data

  • Following execution is more difficult because your Actor Framework process is asynchronous which was your requirement.  There is no "highlight execution" for Actors, but a debug log file is pretty quick to implement.  Since your initial design only has 3 VIs, you could just open all of them and highlight execution to watch.  
  • How do you propose to pass data to the parallel loop?  You will have to use a by reference method or something on the synchronization palette.  The AF solves this with messaging.

The advantage of the DVR method is speed/ease of development and memory usage.  It comes with a few rusty nails...

CLA, CTA
Message 25 of 34
(1,604 Views)

Thanks to David Staab and to LVB for further clarification on the DVR method. I think I have been lucky because so far the code inside the inplace structures has never taken more than a second. But I will keep this in mind and go back to my old ways of using single element queues.

Thanks,

Fab

For an opportunity to learn from experienced developers / entrepeneurs (Steve, Joerg, and Brian amongst them):
Check out DSH Pragmatic Software Development Workshop!

DQMH Lead Architect * DQMH Trusted Advisor * Certified LabVIEW Architect * Certified LabVIEW Embedded Developer * Certified Professional Instructor * LabVIEW Champion * Code Janitor

Have you been nice to future you?
0 Kudos
Message 26 of 34
(1,604 Views)

Hi, sorry to confuse, but I'm also GotRobotFriends (due to ongoing confusion about what my log-in credentials are).

Anyway, I see what you're saying, but have a couple of problems with it. Firstly, in my version of the Actor Framework Library (the most recent one) I can't seem to find a "Time-Delayed Message".


Secondly, it seems like an adequate and, within the constraints of AF, elegant solution for slow control problems, but what about when I want to control something at kHz rates? Of course I haven't benchmarked it, but I'm dubious about the overhead required for the messaging system where an actor is just sending time-delayed messages to itself.

0 Kudos
Message 27 of 34
(1,604 Views)

The "Milliseconds To Wait" input is an I32. I've sent them at 1ms intervals for a "long time". I didn't like the effect on trace execution, but the messages worked.

af.png

0 Kudos
Message 28 of 34
(1,604 Views)

Ahh ty, I was looking in the library, not at the pallette.

0 Kudos
Message 29 of 34
(1,604 Views)

FabiolaDelaCueva wrote:

I will keep this in mind and go back to my old ways of using single element queues.

Don't throw that baby out with the bathwater! DVRs are groovy for the right things.

  • You may want a firm mutex on your data when it's being accessed. For example, I'm working on a circular buffer implementation right now and have to lock out the reader when new data is being buffered by the writer. I store the buffer (array) in a DVR and access it from there to keep the processes from stomping on each other. I could use a SEQ, but I might ignorantly write a third process someday that tries to preview the queue and gets itself all messed up because of that action.
  • You can dynamically dispatch off DVRs of classes and class property nodes, which is very nice for things like ESF-based singletons.
  • Other reasons not bubbling to the top of my head at the moment.
0 Kudos
Message 30 of 34
(1,604 Views)