From 11:00 PM CDT Friday, May 10 – 02:30 PM CDT Saturday, May 11 (04:00 AM UTC – 07:30 PM UTC), ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Auto-stopping dynamically launched nested actors

bmitchell wrote:

A correct answer will directly address why the Launch Nested Actor.vi is setting a property on the actor object in lieu of sending a message.

There's a few reasons. None of them are absolute technical wins for the property mechanism, but I believe they strongly favor the property mechanism over messaging. Item #4 is the strongest argument, IMHO, but I list it last because the others build toward it.

0. You can use a messaging mechanism if you want:

vi.lib\ActorFramework\Actor\Send Launch Nested Actor Msg.vi

This is not *exactly* what you're asking for... this puts the actual launch of the actor  into the message queue, instead of doing it immediately and only posting the registration. But the next bullet point addresses that.

1. The Actor Core message handling loop is not guaranteed to run even once if there's an error going into it. It will jump directly to calling Stop. The nested actors need to already be in the actor if they're going to be told to shut down. I could create a message for Register Newly Launched Nested Actor Msg and give that message an override for Drop Message so that if the message never gets handled, the message sends Stop Msg to the nested actor. It seemed like a lot of mechanism that was generally unneeded for a synchronous launch operation. If you want asynchronous launch, you have the message class I mentioned earlier.

2. If the "Actor out" was not modified,  that would allow people to fork the Actor wire and successfully launch nested actors from within their secondary Actor Core loops. Anything that encourages forking of the Actor wire is bad in my book. It has been the source of huge numbers of bugs and confusion. I'd rather emphasize that you need the real Actor object for all activities on the Actor object.

3. It makes it easy to serialize Launch Nested Actor calls even when you aren't wiring up the error wires. Not everyone connects their error wires all the time.

4. In many cases, more fields need to be updated in the caller actor than just the internal list of nested actors to stop. Those need to be registered into local fields of the private data control. In other words, there's more modifications to be done than just the Actor class. So if you're going to update those fields synchronously, then the registration of the stop message should probably also be synchronous. If you're going to do the whole thing asynchronously, use the posted message.

5. Taken alltogether, if I were going to split the launch from the registration, I would remove the "Nested Actor's Enqueuer" output from "Launch Nested Actor.vi" in order to avoid problems where the nested actor is live, getting messages from the secondary Actor Core loops but still not yet registered at all with the caller actor. That would make the system correct but at a pretty high usability cost, IMHO. I'd rather keep the system correct with lower usability cost, which means synchronous registration.

Make sense?

0 Kudos
Message 31 of 34
(1,030 Views)

I think I've answered this challenge in my other post. There is one small point I want to make here because of a particular phrase bmitchell used:

bmitchell wrote:

The point is that using the actor framework provided VI, a property is set on an actor instead of sending a message to itself. The entire point of the actor framework is to update the state of an actor through messaging once launched. The Launch Nested Actor.vi is NOT doing that.

bmitchell makes a good point in general. But in the specific, there are two phases to an actor object's lifetime -- the time when it is modifiable as a local object and the time when it is modifiable only through messaging. It is perfectly legit for the AF to offer methods that modify the actor object directly; such methods are only invokable when you have access to the object as an object (as opposed to the object as an enqueuer).

You can distinguish such methods easily enough within the AF -- they're the ones that have both an "actor in" and an "actor out". If the actor object isn't modified within the function, I remove the "actor out" terminal. I strongly encourage all LVOOP APIs to do the same.

0 Kudos
Message 32 of 34
(1,030 Views)

Just a reminder... Launch Nested Actor.vi CAN be invoked as a message:

vi.lib\ActorFramework\Actor\Send Launch Nested Actor Msg.vi

My post from a few minutes ago goes into the distinction between this and an alternate architecture where we might have a message solely for regsitering nested actors after they launch.

0 Kudos
Message 33 of 34
(1,030 Views)

AristosQueue wrote:

There's a few reasons.

1. The Actor Core message handling loop is not guaranteed to run even once if there's an error going into it. It will jump directly to calling Stop. The nested actors need to already be in the actor if they're going to be told to shut down. I could create a message for Register Newly Launched Nested Actor Msg and give that message an override for Drop Message so that if the message never gets handled, the message sends Stop Msg to the nested actor. It seemed like a lot of mechanism that was generally unneeded for a synchronous launch operation. If you want asynchronous launch, you have the message class I mentioned earlier.

I would expand on this with an observation.

A significant fraction of nested actors are launched in Actor Core at startup.  Launch Nested Actor, as coded, is just about the most straightforward way to do this.  Launch the nested actors, pass the calling actor into Call Parent Node, and you're done.  Some additional fraction of nested actors are launched as the result of a message that is not "Launch New Actor".  (i.e. this particular actor is given some information, and responds by launching a nested actor, but perhaps its parent or siblings use another mechanism.)  Again, Launch Nested actor, as coded, is the most straightforward solution.

Adding a registration message to Launch Nested Actor means that, in these two use cases (one of them very common), you take a performance hit for packaging, sending, receiving, and processing a message.  Small, but still there.  Furthermore, that message goes to the end of the line; the calling actor may have any number of messages stacked up before the registration message, and that's a period and set of tasks where the nested actor is not available to its caller.  (Yes, we could make that message High priority, so it will jump most of your actor's messages, but not the other High priority ones.  And it won't trump Last Ack or Emergency Stop.) 

Finally (and related to AQ's point 4), if you want to be able to talk to your nested actor, you must do something unique when you register the nested actor.  Usually, that means a named enqueuer attribute in the caller's class data.  If we made Launch Nested Actor register the nested actor via a message, we would have to give you the ability to override the method that message targets, so you could add this unique code.

With Launch Nested Actor in its current form, you have extra performance burdens and extra work to do in cases where you want to launch a nested actor from a helper loop.  You don't like this extra work, and you just want the framework to handle it.  I submit that, if we were to change Launch Nested Actor as you suggest, you would have extra performance burdens and extra work every time you launch a nested actor, including some very common use cases where, incidentally, a cleaner solution exists.

0 Kudos
Message 34 of 34
(1,030 Views)