Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Avoid sending messages to self *from within the message handling loop*

[AQ note: I branched this from another discussion to prevent tangents there... Daklu had stated that avoiding having messages that the actor sent to itself was possible. testingHotAir asked for clarification on how.]

[AQ note: I changed the title of this thread so that future users of AF who search the forums are not confused by the title before they read the body of this discussion. There are two types of "self messages" -- those that come from within the message handling loop itself (i.e. an actor that handles one message and posts another to itself as part of that handling) and those that are done from parallel loops in Actor Core. Daklu is discussing the first kind.]

testingHotAir wrote:

Hi Daklu,

Could you expand on how it's "dirt simple to avoid" sending self messages? I have a whole class of UI actors that send messages to themselves to handle front panel events and to update controls with calculation results, and I really can't think of an easy way to avoid doing that.

The general strategy is for each message that you need to send to yourself, put that message handling code in a sub vi and use the sub vi in the message handler.  Anywhere where you would normally send that message to yourself, use the sub vi instead.

That said, if you are using name/data messages (with a case structure) instead of command pattern messages (as in the AF,) you may not want to route control references into sub vis for UI updates.  What I usually do for UI updates is have a helper loop (not my UI actor's message handling loop) dedicated to updating the UI.  The MHL receives a message indicating some UI elements need updating, and it in turn sends one or more messages to the UI update loop with the new values for the controls.

[Edit - Alternatively you can just create local variables from the front panel controls that need to be updated in multiple message handlers.]

Message was edited by: AristosQueue

0 Kudos
Message 1 of 21
(14,189 Views)

Daklu: That works only for messages that you send to yourself from within the message handling loop. testingHotAir is asking about message that a parallel loop in Actor Core would send to the message handling loop. I don't think your strategy works for those because a subVI doesn't have the actor's state information. For that, you need self messages. (Or you need to eliminate the parallel loop in favor of a nested actor, but that isn't possible in several instances either because the waiting is on something other than a message queue (UI uses events) or because a resource needs to be polled (common in very low level hardware APIs or network monitoring).

0 Kudos
Message 2 of 21
(5,707 Views)

AristosQueue wrote:

Daklu: That works only for messages that you send to yourself from within the message handling loop. testingHotAir is asking about message that a parallel loop in Actor Core would send to the message handling loop. 

Ah, I see the confusion.  I was objecting to having a loop send messages to itself (as often seen in QSM implementations,) not exchanging messages between loops inside an actor.  (I view loops within an actor as separate entities so don't naturally consider sending a message from a helper loop to the MHL "sending a self message," even though that may be the language the AF uses.)  I do not object to sending messages between loops inside an actor--in fact, it is necessary.

0 Kudos
Message 3 of 21
(5,707 Views)

I have a very specific example when I need self addressed messages. (Although I can think of another way to do it - that way I only need self addressed messages form a helper loop )

I have a HW actor. It's part of a system that has a central CONFIG actor. CONFIG actor sends all config data changes to actors that are subscribed. HW is subscribed, so it has to be aware to get the updates pseudo-real-time (I hope the phrase is exact enough).

However, HW actor also has to poll the HW for input source presence. In case there is a source it starts reading data. If not, it keeps on polling.

I see two ways to implement it:

  1. Create messages that
    1. poll the hardware (POLL)
    2. acquire data (ACQ)
      and use the POLL to send self addressed message to itself or to ACQ based on it's result.
  2. Create a helper loop that uses the polling and acquisition methods in a state machine. However if I have a helper loop, I have no access to config data, which I may want to check. I have to make a copy of all config data stored in my actor and store the copies in the helper loop. I also need self adressed messages to get the acquired data in the actor's state data.

I have the feeling that creating the "loop" with self addressed messages is closer to the Actor Model, and I personally like it more. By using helper loops I loose all the state data of my actor. Sometimes it is more work to send the state data to the helper loop, than the simplicity of using a state machine in the helper loop lets me to spare.

What do you think about this situation? Any of the solutions inherently bad? Any third solutions that seem to more elegant?

0 Kudos
Message 4 of 21
(5,707 Views)

komorbela wrote:

What do you think about this situation? Any of the solutions inherently bad? Any third solutions that seem to more elegant?

Here's how I handle situations like this...

Create a metronome helper loop whose sole task is to send a POLL message to the actor's MHL every n seconds.  Place your ACQ code in a sub vi.  (I'm assuming this actor must expose the ACQ message to other actors.)  Put the ACQ sub vi in your ACQ message handler.  In the POLL message handler, place a case structure after the hardware detection code.  Put the ACQ sub vi in the true case, and leave the false case empty.  No loops sending messages to themself.

(This also assumes the process of acquiring data from the hardware doesn't take so long as to cause the message queue to get backed up.  If it does, I'd create a sub actor whose responsibility is restricted to polling and acquisition.)

Having a loop send messages to itself isn't inherently bad--it is possible to do it safely and correctly.  And when there are only one or two self messages, the code appears less complex than the implementations I use.  The problem with self sent messages is they do not scale well at all.  As you add more messages the complexity increases non-linearly.  (Years ago I spent 3 days untangling the execution path of one message in a QSM.)  Once you start using self sent messages in a loop, it's hard to convice yourself it's worth the effort to go back and use a different implementation.

0 Kudos
Message 5 of 21
(5,707 Views)

I've been handling that situation in a similar way, though I always create a sub actor and implement the "metronome" in the actor core.

CLAD
0 Kudos
Message 6 of 21
(5,707 Views)

Thanks for the suggestion, however the solution is not applicable to this exact problem. I think I was not clear enough in expressing my thoughts I try again:

So, after POLL has found the input source, the ACQ has to run repeatedly and as fast as the hardware pushes the data. One ACQ run receives a given size of the data, say 100 data points, lasting about 10 ms, or so. If ACQ noticed loss of input source (with timing out or receiving error) it calls POLL again.

And in the meantime this exact actor (HW) has to receive config data to know where to send the acquired data. It doesn't have any other purpose than polling and acquiring, but it still needs to receives config data, so methods have to be atomic (it also needs to stop properly, so atomicity is a must). So this actor is already similar to the sub actor that you suggest:

(This also assumes the process of acquiring data from the hardware doesn't take so long as to cause the message queue to get backed up.  If it does, I'd create a sub actor whose responsibility is restricted to polling and acquisition.)

Maybe I still should cut it in two and have one actor that has the up to date config data, and a nested one for polling and acquisition? I know it may solve the problem, but I like to create only as many actors as necessary...

0 Kudos
Message 7 of 21
(5,707 Views)

komorbela wrote:

Maybe I still should cut it in two and have one actor that has the up to date config data, and a nested one for polling and acquisition? I know it may solve the problem, but I like to create only as many actors as necessary...

There are lots of ways you can implement this, and using a nested actor for polling and acquisition is one solution that I think would work fine.  If you don't want to implement a full-blown actor, another possible solution is to create a behavioral state machine helper loop that implements the polling and acquisition and sends it to the MHL.  Here is an example of one way to implement the helper loop.

Capture.PNG

Message 8 of 21
(5,707 Views)

Side comments on using a structure like the one Daklu shows:

One can use the Notifier to hold state informtion that the helper loop needs, and one can do the loop timing with the "Wait on Notifier" timeout (rather than a standard timing function).  This allows the main loop to post new controlling state information and have the helper loop respond immediatly (rather than wait up to 10 seconds as in the example).

Message 9 of 21
(5,707 Views)

Good tips James.

I've used the notifier to pass information to the helper loop like you described, and agree it works well as long as the helper loop is kept simple.  If you get into a situations where you're casing out to different procedures based on a data in the notifier, you're better off refactoring it into a real actor.

Message 10 of 21
(5,707 Views)