Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Quick question on sending an enqueuer to another actor

Solved!
Go to solution

From what I see, the passing of the EnQr is correct, but not the usage.

The seqeuncing in FlightSimUI:Actor Core.vi is simply incorrect: you are extracting the EnQr from your objects private data, before it has been written a correct value at all. This can't be done before the parent call of Actor Core has been started.

ActorCore.png

DataFlow

Added screenshot

Message 11 of 23
(2,147 Views)

Thank you Oli, that makes sense. But I still can't see how to code this properly - I'm thinking I need to receive the message inside the while loop/event case, right? Do I need to use a shift register to retain the CalcAirspeed enqueuer? Or some other method?

0 Kudos
Message 12 of 23
(2,147 Views)
Solution
Accepted by DMurrayIRL

Use the event structure to fire messages to the Actor itself (e.g. ThrottleChanged) with the neccessary data payload (Throttle Value). The Do.vi called by Actor Core can handle this message using the correct EnQr taken form the Actors' private data.

0 Kudos
Message 13 of 23
(2,147 Views)

Nope... still don't see it. I'm not dumb, honestly! But I'm clearly missing something obvious here. When you say "Use the event structure to fire messages to the Actor itself..." , which event structure are you talking about, and which Actor?

0 Kudos
Message 14 of 23
(2,147 Views)

Okay - got it! Thanks for your help.

Here's what I did, in case anyone else is stuck on this. (I'm a bit embarassed to say I found this somewhat difficult!):

1. Added a new event called "CalcAirspeed MQEvent" to the "FlightSim UI" actor, with an enqueuer as the event data.

2. In the "FlightSim UI" actor event case, routed the "FlightSim UI" wire through as a shift register.

3. Also in the "FlightSim UI" event case, added a dynamic User Event which updated the "CalcAirspeed" Enqueuer when the CalcAirspeed MQEvent fired.

4. Created a method and message in FlightSim UI to fire the user event.

5. Back in the "CalcAirspeed" actor core, I use the message created in (4) to send the "CalcAirspeed" enqueuer back to the "FlightSim UI" actor.

0 Kudos
Message 15 of 23
(2,147 Views)

Really sounds complicated...

I've attached an example of what I think is kinda best practice.

I usually try to keep my communication paths seperated: everything that's working with actor private data (E.g. the EnQr of the other Actor ) gets handled by Actor Core and the methods called by it.

The parallel event loop does nothing but translating Events from the UI into messages being processed by Actor Core.

I have to admit, I haven't neither really tested this before posting nor is the code really beautiful. Created this before the first morning coffee

So basically, what it does:

the event loop sends a message object to the Actor; the message handling routine takes the EnQr of the "Destination" / "Receiving" / whatever Actor from the private data and sends another message object (not implemented in this example) to it.

Feel free to ask further questions.

0 Kudos
Message 16 of 23
(2,147 Views)

In your example, are you effectively sending the message (i.e. a message with the new slide value) to yourself, and then sending on the slide value to the desired actor (in a new message, not yet created in your example)? I find this quite... odd (Forgive my impoliteness!). It certainly seems cleaner than the way I did it, but is this really standard? I don't like the thought of sending a message to myself, just to forward it on to another actor.

Also, I'm wondering that even if I use this method, I may still have the issue that I had in my original code, i.e. I still need to find a way to initialize the Receiver EnQr in the private data of this actor ("MyActor" in your example). I think the reason I had the problem was because I moved away from a top-down Actor Tree where it was easy for callers and callee's to know about each other. I'm not sure your method solves that, although I haven't tried to implement it yet.

Anyway, plenty for me to think about. Thanks for your help thus far.

0 Kudos
Message 17 of 23
(2,147 Views)

Sorry to pop in again, but I have some thoughts that may help.

First of all I didn't open Oli's code yet, I only react to your recent post.

I usually do it similarly to the way Oli describes. I even find it nice for the following reasons:

Actors can be reached only by messages. Messages arrive to the Actor Core (the original, not the overrides). So the cleanest way to send messages is to send it from actor core's loop, (from a message's do.vi). That way actors talk to actors and the data received can be easily stored in the actor's private data. If needed it can be processed and stored afterwards.

If you start to "export" part of your communication to the helper loop (often an event handling loop if you implement a UI) you may want to process data in the same loop. It results in a split actor that has some data in the actor core's loop and some in the helper loop. In some cases it is only inconvenient, because you may need data from both loops for some methods, but in some cases it can lead to bugs:

Let's say you have all the data you need in the actor's private data, but you make copy of some in the helper loop to make message sending easier from there (UI). You also let the user modify this data in helper loop. Later you use the same data for a method, but in the actor core. You will use an outdated copy and your actor will not work properly.

Another reason to keep messaging out of the event handling loop is to keep that responsive.

If I use the actor core override as a UI I send all user input to the actor core as a self-addressed-message and send all processed data to be displayed to the UI as user events. There are other valid methods to communicate with the helper loop, but I found these to work well and keep my code clean.

One disadvantage of the self-addressed-message is that you need two messages to send a user input to another actor. In some extreme cases, for example if your helper loop is a fast data acquisition loop, you may want to send data directly from the helper loop to another actor. But in this case extra care should be taken to live with the fact that you will not be able to access the acquired data in the actor core's loop.

I hope it helps a bit to understand why I highly suggest to send messages to other actors from the actor core's loop (by placing it in a message's do.vi).

0 Kudos
Message 18 of 23
(2,147 Views)

Just a quick reply for now as it's late here... komorbela, your post makes me realise that I've been thinking about AF all wrong. I thought the point was to override the actor core, and do all your messaging from within a loop in the override. So I'm left with a sinking feeling that I'm pretty much back to square one... Anyway, I'll have a better look through your post tomorrow.

0 Kudos
Message 19 of 23
(2,147 Views)

DMurrayIRL schrieb:

I find this quite... odd (Forgive my impoliteness!).

No worries

DMurrayIRL schrieb:

It certainly seems cleaner than the way I did it, but is this really standard? I don't like the thought of sending a message to myself, just to forward it on to another actor.

Talking about standards is always a difficult thing... One of my coding styles' primary objectives is to keep a clear structure/ hierarchy on data storage (data in a single place, no copies) and communication (usually going through the whole tree), which of course causes a certain amount of overhead and a bunch of code (e.g. message to self + message to receiver as mentioned above).

But when it comes to debugging or adding new features I'm usually better of.

I have seen to much messy code during my time programming....

Well, that's my opinion...

DMurrayIRL schrieb:

Also, I'm wondering that even if I use this method, I may still have the issue that I had in my original code, i.e. I still need to find a way to initialize the Receiver EnQr in the private data of this actor ("MyActor" in your example).

Obviously to set the Receiver EnQr, you would send the Set Receiver EnQr Msg from another Actor.

So the first thing to do after the Actor has been launched is to send this message. But nevertheless, there are scenarios, where you can't be sure, Reciever EnQr has been properly initialised before usage. That's why my example, I'm checking if it is valid before using it. Disposing the message if it is not. Or, if needed re-queue the message and try again later. Or whatever strategy you choose.

DMurrayIRL schrieb:

Anyway, plenty for me to think about. Thanks for your help thus far.

Pleasure

The AF is simply a different paradigm for programming. Has taken me (and sometimes is still taking) me some amount of headache.  Keep trying!

0 Kudos
Message 20 of 23
(2,147 Views)