Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

How to launch multiple copies of an actor dynamically

Solved!
Go to solution

Hi All

Could someone explain me how to launch an actor X for every time an event Y occurs? Taking the LV actor framework template as an example:

Each time an event (could be the user clicking a button on the front panel of the root actor) occurs, I would like to launch an actor X. That is, I would like to launch the actor form inside the event loop (marked A on the screenshot below). Clicking the button N times, would then give me N copies of the X-actor running. I found some inspiration in this thread, but it does not seem to solve my issue

https://forums.ni.com/t5/Actor-Framework-Discussions/Launching-Nested-Actors-Dynamically-after-Root-...

 

If I understand how the actor framework works, the problem is that each nested actor needs to have a queue on the root actor's private data cluster control (see 2nd picture below). But how can I put N queues in the private data cluster?

 

Second problem is that the nested actor's enqueuer needs to be fed into the data cluster of the root actor (see encircled code in the first picture below). As demonstrated in the example, which I linked to above, this can be solved by having a method of the root actor launching the nested actor. The method would launch the actor and wire its' enqueuer into its' own data cluster. However it still requires that the root actor's private data cluster control contains a queue for the X-actor. 

 

I hope my description makes sense. If someone could give an example that would be fantastic!

 

Udklip.PNG

 

Udklip2.PNG

0 Kudos
Message 1 of 9
(4,696 Views)
Sorry preseed for time. Can't explain thoroughly but have the button send a message to self and launch the nested actor there. Store the enqueuers in an array inside the actor's private data
Sam Taggart
CLA, CPI, CTD, LabVIEW Champion
DQMH Trusted Advisor
Read about my thoughts on Software Development at sasworkshops.com/blog
GCentral
0 Kudos
Message 2 of 9
(4,680 Views)
Solution
Accepted by topic author Peter1305

Do you want the nested actor queues accessible within the actor core (where messages are handled)? If so I've always done things like this by sending a message to myself from the helper loop and doing the action in the message handler. This way I have access to the actor data (the copy that actually gets used during message handling). In your case just send a message to yourself every time an event is hit. This adds some plumbing work, but gets the job done. It's also why I try to avoid using helper loops as much as possible (why not create another actor?). Looks like you have one to handle the UI which is one of the cases where I don't think you can avoid it though.

 

To have N queues in the private data I'd use an array of queues. If you need some other way of accessing the queue other than index, then you could use a map (native in LV2019 and you can use variant attributes otherwise).

 

Message 3 of 9
(4,673 Views)

To have a dynamic number of Actors you certainly need to use something like an array of Enqueuers. A Map is another option, and as mbremer points out allows you to use a non-integer key (or a non-consecutive integer, etc) as the lookup "key". Which is preferably depends on how you want to access the specific enqueuer when you wish to send the callee a message.

 

You will probably need to use a message, as Sam highlighted, because otherwise you cannot affect the contents of the caller's private data in a particularly useful way (you can make a copy by forking the wire, but this copy won't be the Actor that's running - it will be essentially just a normal object that you could keep in a shift register).

 

If you don't need to send messages from messages then it should be possible to avoid the "Launch Other Actor Msg" by storing the enqueuers in a shift register in your Actor Core (either as an array or Map). This won't allow you to message them from anywhere except that loop though (and if you come up with complicated workarounds like storing the array in a notifier then you'd really be much better sticking within the framework and storing them in the Actor's private data (caller actor)). So do this only if you're confident you'll never want to message them from outside of your Event loop (i.e. really, don't do this...)


GCentral
0 Kudos
Message 4 of 9
(4,642 Views)
Solution
Accepted by topic author Peter1305

Here You can see a small example. Run the launcher.vi.

0 Kudos
Message 5 of 9
(4,626 Views)

@cbutcher wrote:

 

 

If you don't need to send messages from messages then it should be possible to avoid the "Launch Other Actor Msg" by storing the enqueuers in a shift register in your Actor Core (either as an array or Map). This won't allow you to message them from anywhere except that loop though (and if you come up with complicated workarounds like storing the array in a notifier then you'd really be much better sticking within the framework and storing them in the Actor's private data (caller actor)). So do this only if you're confident you'll never want to message them from outside of your Event loop (i.e. really, don't do this...)


While what Christian describes here is technically possible, do future you a favor and follow Christian's advice and don't do this.  In general don't store state in the helper loop unless you absolutely have to.

Sam Taggart
CLA, CPI, CTD, LabVIEW Champion
DQMH Trusted Advisor
Read about my thoughts on Software Development at sasworkshops.com/blog
GCentral
0 Kudos
Message 6 of 9
(4,600 Views)

You could also use an Action Engine to store the Enqueuers, though I think the best way is to just send yourself a message. (I'm not a huge fan of AE's as they can be kind of hard to debug, but they certainly have their uses)

0 Kudos
Message 7 of 9
(4,590 Views)

Thanks a lot to all of you for your replies. They have all been helpful. Let me answer some of your questions:

 

I would like to have access to the enqueuers of the nested actors in the root actor's core. It is possible that I could write my program without, but that would require a complete restructuring, so I would have to think more about that.

 

p4keal, thanks for your example, but it seems like the enqueuers of the nested actors are not available in the root actor's core, so it is doesn't solve all my problems. It is still useful though!

 

Storing the N enqueuers in an array seems appealing to me. I have tried to combine this with the "launch nested actor by method" approach like in p4keal's example, and results seem promising so far! I will get back, if I have further questions. Thanks again

0 Kudos
Message 8 of 9
(4,528 Views)

If You need enquers of nested actor - just define an array of enquers in your root's data cluster. Or use a variant to store them.

Here is v2 of example. Start and close some nested actors and watch root ui. You can only access root's data from an action vi. If you want to send a message to a nested actor -> define a action vi and a message around it. For the second step You can use wizzard. You can get enquer from the variant by actor's name with "get variant attribute.vi"

0 Kudos
Message 9 of 9
(4,493 Views)