Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Communicate Between Parallel Nested Actors

Solved!
Go to solution

Basically the Caller, receives the message from it's nested actor (so that would typically be a concrete child of an abstract message) and then when the caller receives it, the Do.vi for that message simply sends a concrete message to the other nested actor.

 

So the downside to the normal strict hierarchical, is that you end up with a bunch of messages that do nothing but forward messages along the chain (of course you are not technically forwarding the messaging object but sending a new message which has the same intent). 

 

So yes as in the last line your post you do end up with a lot of "forward this information to actor B messages"

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 21 of 29
(4,403 Views)

For the logger application, I would create a parent actor that owns an enqueuer for the logger in its private data and make all your actors that need to log data inherit from that.  Then you can write one method in your parent class called "log string" that takes a string and sends it to the logger.

 

Then you have to launch the logger first so you can get its enqueuer and everytime you launch a nested actor, you give it the enqueuer to the logger.  Then each of those nested actors can call the "log string method".   

 

The parent class can protect the logger enqueuer so that other loops can't accidentally shut it down or anything or send it some other message.  

 

 

 

Sam Taggart
CLA, CPI, CTD, LabVIEW Champion
DQMH Trusted Advisor
Read about my thoughts on Software Development at sasworkshops.com/blog
GCentral
Message 22 of 29
(4,400 Views)

@CanadaGuy wrote:

I see...I have been paying little to no attention to the purpose of a message (data or control), so it appears I need to start distinguishing between the two.

 


Only if you break hierarchical  messaging. 🙂  And truthfully, when I say control messages should always follow the tree, I mean it in the same way as when I say all messages should follow the tree. It's safer, but under certain circumstances it might be okay to violate that rule.

 

(Hint: Not wanting to create the forwarding messages isn't a valid reason to use direct messaging.)

 

Is there an example showing perhaps 2-3 nested levels of actors where the messaging is passed up and down the tree? I don't think I've seen one yet, and if I did, I didn't recognize it.

I don't use the AF, so I don't have one. I'd be surprised if there isn't one out there. 

0 Kudos
Message 23 of 29
(4,394 Views)

When they release the videos from GDevCon you should check out Dr. Powell's presentation on messaging.  It doesn't have the AF example you are looking for, but it does have a lot of really useful information and theory about messaging paradigms including peer networks versus a tree structure.  It talks about the pitfalls of breaking the tree hierarchy.  Generally, I only break it as a last result and with good reason.

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 24 of 29
(4,387 Views)

@CanadaGuy wrote:

I have a root actor that launches two nested actors (side by side in parallel, not cascaded). The root actor is a UI actor. The first nested actor is a logging actor, the second actor is a simulation actor. For messages from each callee to the caller actor, I'm using the abstract/child message approach so the nested actors are not dependent on the root actor.

 

How do I send a log message from the simulation actor to the logging actor? One method I thought would be to includes a user event in the root actor that will fire when a log message is received from the simulation actor, and forward it to the logging actor. The other thought I had was that I could initialize the logging actor first, get its enqueuer, then initialize the simulation actor with the logging enqueuer in place. Does this create some dependencies that I'm not aware of?


I would like to suggest an idea:
To avoid generating of may be unnecessary forwarding messages,
You can override the Receive Message.vi in Root Actor. You must also define a base class for all logger messages, e.g. Msg for Logger.lvclass inheriting from Message.lvclass. For the logger messages You have to change the parent class from Message.lvclass to Msg for Logger.lvclass.

Class Diagramm and Root.Receive Message.png

In Receive Message.vi You can verify that the message is derived from Msg for Logger.lvclass and forward the message to Logger Actor. Otherwise, the parent Receive Message.vi is called and the root proceed the message by itself. I attach a sample project (LV2014). Run the Launcher.vi

Message 25 of 29
(4,344 Views)

@p4keal wrote:

@CanadaGuy wrote:

...


I would like to suggest an idea:
To avoid generating of may be unnecessary forwarding messages,
You can override the Receive Message.vi in Root Actor. You must also define a base class for all logger messages, e.g. Msg for Logger.lvclass inheriting from Message.lvclass. For the logger messages You have to change the parent class from Message.lvclass to Msg for Logger.lvclass.

Class Diagramm and Root.Receive Message.png

In Receive Message.vi You can verify that the message is derived from Msg for Logger.lvclass and forward the message to Logger Actor. Otherwise, the parent Receive Message.vi is called and the root proceed the message by itself. I attach a sample project (LV2014). Run the Launcher.vi


Thanks for posting this, I enjoyed learning about modifying the default behavior of Receive Message.vi, which I hadn't thought about before.

 

In 2020 now, I'm trying to understand if this problem (i.e. "avoid generating of may be unnecessary forwarding messages") is still relevant. If I use an interface "log message" implemented by root, log, and all N nested actors which can generate a log event, then I need N+2 implementations of the log message interface. Is that N+2 implementations the problem of unnecessary forwarding messages?

 

In your implementation, you have override the Receive Message.vi in Root Actor, create a new Logger.lvclass inheriting from Message.lvclass, and then put that send log entry class within the private data of N nested actors which can generate a log event.

 

These methods (LabVIEW 2020 interface) and your method seem comparable in amount of code-burden, right?

 

 


------------------------------------------------------------------------------------

Please join the conversation to keep LabVIEW relevant for future engineers. Price hikes plus SaaS model has many current engineers seriously concerned...

Read the Conversation Here, LabVIEW-subscription-model-for-2022
0 Kudos
Message 26 of 29
(2,907 Views)

@Taggart wrote:

For the logger application, I would create a parent actor that owns an enqueuer for the logger in its private data and make all your actors that need to log data inherit from that.  Then you can write one method in your parent class called "log string" that takes a string and sends it to the logger.

 

Then you have to launch the logger first so you can get its enqueuer and everytime you launch a nested actor, you give it the enqueuer to the logger.  Then each of those nested actors can call the "log string method".   

 

The parent class can protect the logger enqueuer so that other loops can't accidentally shut it down or anything or send it some other message.  


I'm also trying to understand the relevancy of this (valid) solution now that we have the 2020 version. 

 

So if I instead use a interface "log message" inherited by root, log, and all N nested actors which can generate a log event, then all my N actors can fire off send log event messages to root. In roots implementation of the interface, it forwards it off to logger actor. 

 

Does that capture all of the benefit of your solution & reduce coupling (b/c the nested actors don't inherit from root) but not zero coupling (as the nested actors do all inherit from the interface).


------------------------------------------------------------------------------------

Please join the conversation to keep LabVIEW relevant for future engineers. Price hikes plus SaaS model has many current engineers seriously concerned...

Read the Conversation Here, LabVIEW-subscription-model-for-2022
0 Kudos
Message 27 of 29
(2,901 Views)

Would you provide me an example of it for learning AF?

0 Kudos
Message 28 of 29
(1,661 Views)

You have several options as described in this thread. If you want to learn overwrite message receive approach, example is available three posts above:
https://forums.ni.com/t5/Actor-Framework-Discussions/Communicate-Between-Parallel-Nested-Actors/m-p/...

If you want to use the abstract message method as specified in solution: I would suggest using interfaces instead of abstract messages.

Update:
to learn about interfaces in LV see here: https://youtu.be/1lFMZe9SwMY?si=zrOYHMMFdaeDS2id

 

0 Kudos
Message 29 of 29
(1,622 Views)