Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Is sending message to a nested actor from helper loop of root bad code?

Solved!
Go to solution

OneOfTheDans said it much more succinctly than I did. 🙂

0 Kudos
Message 11 of 18
(1,183 Views)

@AristosQueue (NI) wrote:

@WavePacket wrote:

^I think we're in agreement - the possibility for stale actor data exists so if the enqueuer could change at runtime the helper loop will have to get the new queue somehow. For example, perhaps root will fire an event which updates a shift register in the helper loop. This still feels like I have multiple sources of truth though (the queue in root, and the copy in the helper loop) -- my code smell is going off a bit if I'm honest. 


Sure, if you're doing dynamic launching of nested actors and respawns and whatnot, then you almost certainly need to have the helper loops route their requests through the caller actor instead of talking to the nested actor directly (generally that's way better than trying to update the helper loop with a new nested enqueuer). But that's a highly specialized scenario and not common. Do not use a corner case to rule out a useful tool for the common case. 🙂

 

Remember that any class is supposed to be a coherent (in the technical sense) whole -- it is designed as one piece, with its various methods having awareness of what the other methods are doing. For example, we commonly write private methods that don't sanity check their inputs because the public API of the class is responsible for doing those sanity checks. That principle is important in this discussion:

  • If you've designed your caller actor to maintain a highly dynamic nested actor, you'll write the caller actor's Actor Core to pass messages through the caller actor.
  • But if you've designed a fairly static relationship, particularly one where Launch Nested Actor is right there on the block diagram of Actor Core, then you'll write your helper loops accordingly.

In both cases, you do maintain one source of truth, but you can put that source of truth in the most convenient place without worrying that an element that is independently designed is going to mess with you. The caller actor is coherently designed.

 

Does that make sense?


I think it does. Thanks, I hadn't realized that my first AF project was a highly specialized scenario. That's consistent with why I've had to ask soo many questions on this forum over the last couple of weeks...lol


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

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 12 of 18
(1,169 Views)

What's funny is that the "super dynamic nested" case is the one that AF was designed for, and it is the one I expected to be super common because it was the use case for the original four customers that I was investigating. But over time, it's become clear that static relationships among parallel actors are far more common. So AF handles your case, and handles it well, but a lot of discussion you'll see doesn't necessarily focus on your use case.

0 Kudos
Message 13 of 18
(1,163 Views)

I am going to go out on a limb and disagree with AQ here. I realize that is generally a bad idea, but ...

 

If something changes and your nested needs to know about it, chances are your actor itself should know about it too, so self-enqueuing a message to let your actor know about it is probably a good idea. So once you do that, why have the helper loop notify the nested as well? Just have it notify the actor (itself) and let it (the message handling code ie actor core call parent) decide what to do. The only benefit I see is potentially cutting out the middleman, and I see lots of potential downsides.

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 14 of 18
(1,159 Views)

@AristosQueue (NI) wrote:

 

Remember that any class is supposed to be a coherent (in the technical sense) whole -- it is designed as one piece, with its various methods having awareness of what the other methods are doing. For example, we commonly write private methods that don't sanity check their inputs because the public API of the class is responsible for doing those sanity checks. That principle is important in this discussion:

  • If you've designed your caller actor to maintain a highly dynamic nested actor, you'll write the caller actor's Actor Core to pass messages through the caller actor.
  • But if you've designed a fairly static relationship, particularly one where Launch Nested Actor is right there on the block diagram of Actor Core, then you'll write your helper loops accordingly.

In both cases, you do maintain one source of truth, but you can put that source of truth in the most convenient place without worrying that an element that is independently designed is going to mess with you. The caller actor is coherently designed.

 

Does that make sense?


Yes and no. If you allow people to extend your actor by creating child classes, I could see some problems with this approach. 

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 15 of 18
(1,159 Views)

@Taggart wrote:

If something changes and your nested needs to know about it, chances are your actor itself should know about it too, so self-enqueuing a message to let your actor know about it is probably a good idea. So once you do that, why have the helper loop notify the nested as well?


From my (non-AF) experience, when I have two or more components both messaging a nested component, it is usually that way because the types of messaging are independant.  For example, I might have:
A: manages lifetime; starting and stopping Nested N (and the other two actors B and C)

B: manages showing the Front Panel of various actors including N

C: Uses N for collecting data

 

None of A, B, or C care about the other types of interactions, other than some minor points**  Changing collection?  A and B don't need to know.  User selects a different thing to look at in a Sub Panel?  A and C don't care.

 

Now if it isn't independant like this, then what you say is true.

 

**like A must shutdown C before shutting down N, since C uses N

0 Kudos
Message 16 of 18
(1,141 Views)

Taggart wrote:

> chances are your actor itself should know about it too

 

If "chance" is calculated by actual instances where this is true divided by total number of instances, then chances are not. 🙂 Prior to data, your hypothesis would've been (indeed, was) my hypothesis. But it just doesn't turn out to be true in practice.

0 Kudos
Message 17 of 18
(1,135 Views)

@Taggart wrote:

Yes and no. If you allow people to extend your actor by creating child classes, I could see some problems with this approach. 


The message from the helper loop to the actor is usually private and not dynamic dispatch. The implementation is entirely within the parent actor for all cases I've ever worked on. So any child actors deriving from caller wouldn't hear anything about messages from the helper to caller anyway. If you're trying to manage *caller actor state* of which the nested actor update is a side effect, that's different, and there you would have a message that is probably handled dynamic dispatch. But that isn't a case where the helper loop would be messaging directly anyway because the helper loop wouldn't be trying to message the nested actor... it's goal would be messaging the caller.

 

No dragons on this road that I've met. YMMV, but I'm calling it safe.

Message 18 of 18
(1,131 Views)