Is it supported to allow the caller actor to access to the nested actor object, once it has been launched?
I notice "Launch Nested Actor" takes the Actor in, but it does not come out. It does not come out, I think, until the nested actor stops and you can pick it up again in the "Handle Last Ack Core.vi" override.
Why I want this, is because I am trying to avoid needing to code an object "Initialise" routine in the actor class, which lets me determine run-time parameters (such an actor instance count preserved in the static global in my actor hierarchy base -class). I would like this to be done within the "Pre Launch Init.vi" of my (to be nested) actor class, but that does not execute until you launch. And then the (modified) object is hidden.
I can completely understand if it is (I guess the caller has no business poking inside a running actor). But I just want to read out the actor instance count determined by "Pre Lauch Init.vi", I don't want to write anything.
And in my case also, I suppose an Actor Instance count is not valid until the actor runs, which it doesn't (within an Initialise.vi routine) until I call the "Lauch Nested Actor".
Solved! Go to Solution.
It does not come out... until the nested actor stops and you can pick it up again in the "Handle Last Ack Core.vi" override.
That's correct - once you launch the Actor object, the only way to interact with it is via the Message Enqueuer. Remember that LabVIEW objects are all "by-value", so they can only be in one place at a time. With the Actor Framework, it is in the Actor Core.vi loop (while running). Any use outside that loop would necessarily be a forked copy of the object.
If your class has a static global, you should be able to create a new object at any time and query the total number of instances.
I suppose an Actor Instance count is not valid until the actor runs, which it doesn't (within an Initialise.vi routine) until I call the "Lauch Nested Actor".
It's even a bit worse than that - Pre Launch Init.vi occurs before launching (as the name says). It's possible to have errors launching an Actor, in which case Launch Nested Actor.vi will return those errors and your Actor will have never started. If you're looking for instance count, I think it's safer to put the increment inside an override of Actor Core.vi, immediately before the Call Parent Method node.
I wonder if this protected Actor method would be of use to you. As the documentation states, it is good only for auto-stopping nested actors.
This VI is present in the AF palette. I have never used it, so I don't know if it returns only the immediately nested actors count; or the entire sub-tree of nested actors count.
It's only the immediately nested Actors. Actor.lvclass keeps an array of auto-stop enqueuers it launched. It's just the size of that array.
It sort of feels to me like we've sort of glossed over the important part here.
That's correct - once you launch the Actor object, the only way to interact with it is via the Message Enqueuer.
Is there a reason why you don't want to pass any needed run-time parameters back to the caller by message? Are you sure that the calling actor even needs to know those things?
I sort of suspect that OP may be leaking more details of the nested actors than is necessary, but I don't fully understand the use case either so take that with a grain of salt.
If you just need to know if the actor successfully launched, then just check for an error on Pre-launch Init. If there's no error, your new actor just launched, and you can record the number of them that are currently running.
I could get a message to convey the instance count, but it kind of feels heavy-weight just to read something that is "outside" the asynchronous activity of the actor. And it also means as a caller, I cannot launch another instance until the first instance has successfully sent back a message that I can match up the enqueuer value - which I suppose is not a bad thing as it confirms the actor has actually launched.
But it seems to me a launched actor object contains bother synchronous and asynchronous features. Before launch its ALL synchronous. There is nothing "independent" from the Caller that the to-be-nested actor object consists of. After launch, the actor is then a mix of the synchronous and asynchronous. The asynchronous, I accept, should-not/must-not be touched. But the synchronous stuff I may have added to my actor class implementation, I don't see why launching then locks it away.
It seems there should be "design-time" and "run-time" privacy element to an actor. I have no idea how this might be expressed in code, but it "feels" incomplete.
A class as a conceptual container of an Actor feels inadequate. But that's life.
However, thanks for the answers. Its clarified what I suspected. Still learning the ins & outs of AF. As a relative beginner there are nuances which feel odd, but I'm getting there.
I cannot launch another instance until the first instance has successfully sent back a message that I can match up the enqueuer value - which I suppose is not a bad thing as it confirms the actor has actually launched.
If Pre-launch Init doesn't return an error, then the actor successfully launched. Put as much setup code as you can in that function. If you MUST put it in Actor Core (like, for example, if the launching of one actor depends on it successfully launching its own actors since PLI isn't reentrant), then it sounds like the situation where an extra "Yep I'm initialized" message isn't too bad.
Another way to look at it would be to know that you need a way for an actor to let its caller know that it has "died" somehow (for example, someone pulls the plug on your equipment). Thus, you need to handle decrementing your "number of actors launched" counter in some way.
If you assume that a no-error PLI means +1 to your count, then increment your counter. If Actor Core tries some other setup function and can't actually initialize properly, then it'll throw an error and will be immediately decremented. Consider in your use case- is there a difference to your code if an actor lives for 10 minutes before throwing an error and "dying" or if it lives for 100 milliseconds before doing the same?
From the POV of the Actor Framework, the actor is launched if PLI doesn't return an error. It might not be doing the thing you want it to do yet, but it is launched. If your application has a real difference between "launched" and "doing the thing I want it to do" (aka, initialized) then the framework cannot tell you that, and you need a quick and simple message saying "initialized" sent back to the caller.
Note that the Actor Framework is based on the Actor Model from Computer Science. A central tenet of that model is that "actors" share no "synchronous stuff" whatsoever, and only interact via messages.