From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Actor Core Message Handling

Perhaps I am missing something, but I thought an actor was a queued message handler?

 

I am debugging a program I wrote using Actor Framework and I have a configuration GUI that when it closes, it writes a boolean true or false to a value in memory and then stops the actor core. 

 

When the main GUI receives the last ack from the configuration GUI, it reads the boolean and is supposed to protect the launch of the process, if the CLOSE button on the Configuration GUI was pushed instead of the START button. 

 

Actor Core Message Handling.PNG

 

Immediately after the message to write the boolean to the actor core's memory (using an accessor since its another instance of the class) I call stop core.

 

It doesnt matter if I press CLOSE or START on the Configuration GUI, the sub process starts and should not. It appears that the boolean data is not being written to the actor core's class data before the stop core is executed. 


Should these two messages not be executed in order received? 

 

Close Button Pushed.PNGStart Button Pushed.PNGWhat am I missing here? I can get it to work if I put the stop core inside of the accessor that I am calling from the helper loop, but not if call both messages from the helper loop.

Steven Howell
Controls and Instrumentation Engineer
Jacobs Technologies
NASA Johnson Space Center
0 Kudos
Message 1 of 10
(4,218 Views)

Hi Steven,

 


@StevenHowellPerhaps I am missing something, but I thought an actor was a queued message handler?

 

I am debugging a program I wrote using Actor Framework and I have a configuration GUI that when it closes, it writes a boolean true or false to a value in memory and then stops the actor core. 

 

When the main GUI receives the last ack from the configuration GUI, it reads the boolean and is supposed to protect the launch of the process, if the CLOSE button on the Configuration GUI was pushed instead of the START button. 

 Actor Core Message Handling.PNG


Suppose, the object in the shift register is the Actor object. The wire being forked somewhere on the left (non-visible).

 

Some thoughts:

  • Are the message priorities the same? Have you already tried tweaking at this point?
  • Have you tried to probe the message execution of the "set boolean"? Is the message executed? (BTW: if not, the message would also be delivered within the queue as part of the object being sent by LastAck)
  • Is the object type being cast to correct?

 

 

Message 2 of 10
(4,192 Views)

Not 100% sure of what's happening there, but things to check:

- I second Oli on what's going on upstream in the non-visible part of your Actor Core. You rarely need the Actor object value in helper loops, and you never need shift registers. The internal actor state is maintained in the Actor ancestor class.

- Is your ConfigUI actor even "running" (the parent actor core receiving messages)? If something bad happened in there, and you didn't handle how to close the helper loop, you think the actor is still running normally but it does not actually receive messages as the parent Actor Core had already shut down. Check for errors in your ConfiUI Actor Core VI.

 

Side note:

- Make sure your have a good reason to probe the class name in your Main UI Last Ack as it is prone to issues at a later time (e.g. renamed the class or put it into a lvlib). You could just use the To More Specific Class and look at the error cluster. That also enables you to filter the whole inheritance tree instead of just one class.

 

--Eric

 

Eric M. - Senior Software Engineer
Certified LabVIEW Architect - Certified LabVIEW Embedded Systems Developer - Certified LabWindows™/CVI Developer
Neosoft Technologies inc.

0 Kudos
Message 3 of 10
(4,176 Views)

If we're guessing at causes (and it seems that's the best option, given the available information), I'd also take a swing at a non-default priority on the Send VI for the accessor (the default, as I'm sure you know, is "Normal", but you could set it to a different value at the enqueuer), or a problem with the (Config) Actor leading to an error condition.

 

My first guess was a bad string for the Case Structure, but clearly that wouldn't trigger the launch in either case, whereas you have the launch in both cases.

 

Inverting the logic (Close -> False, Run -> True) might give some idea as to where the setting isn't being set, but it's likely you'll just get the opposite behaviour and no further information.

 


@Eric.Mさんは書きました:

 

Side note:

- Make sure your have a good reason to probe the class name in your Main UI Last Ack as it is prone to issues at a later time (e.g. renamed the class or put it into a lvlib). You could just use the To More Specific Class and look at the error cluster. That also enables you to filter the whole inheritance tree instead of just one class.

 

 


Although I've found checking a class name to be an error-fraught method, it might be that checking against a tree isn't desired. In any case, it doesn't appear to be the cause of the error here (unless there's another case which also launches the Actor in question, and we're looking at the wrong case, but that seems unlikely).


GCentral
0 Kudos
Message 4 of 10
(4,171 Views)

Eric and Oli, 

 

Thank you both for your feedback. When I create a UI Actor, I have always been branching the actor wire and running that to the event handler helper loop. I see now that this is actually not a good practice. 

This practice actually then forces the developer to remember that you now have two locations that you must maintain state data. The actor core and the helper loop. I am better off only wiring the self enqueuer of the actor core to the helper loop and then if state data changes in the helper loop, send a message to call an accessor for the actor core to update its state data. 

Any state data in the helper loop can be maintained locally via a cluster and shift registers on that loop, it doesnt need the actor wire.

 

 

Steven Howell
Controls and Instrumentation Engineer
Jacobs Technologies
NASA Johnson Space Center
0 Kudos
Message 5 of 10
(4,122 Views)

@Eric.M wrote:

Not 100% sure of what's happening there, but things to check:

- I second Oli on what's going on upstream in the non-visible part of your Actor Core. You rarely need the Actor object value in helper loops, and you never need shift registers. The internal actor state is maintained in the Actor ancestor class.

- Is your ConfigUI actor even "running" (the parent actor core receiving messages)? If something bad happened in there, and you didn't handle how to close the helper loop, you think the actor is still running normally but it does not actually receive messages as the parent Actor Core had already shut down. Check for errors in your ConfiUI Actor Core VI.

 

Side note:

- Make sure your have a good reason to probe the class name in your Main UI Last Ack as it is prone to issues at a later time (e.g. renamed the class or put it into a lvlib). You could just use the To More Specific Class and look at the error cluster. That also enables you to filter the whole inheritance tree instead of just one class.

 

--Eric

 


Eric,

 

I am a bit confused by your response. If there is not an error from the actor closing out and reporting back to its caller, how will the error cluster give us the information we need? I tested that and if there is no error, no data is on the error cluster wire. 

 

Would you not need the class wire of the actor that stopped and then go to more specific class to be able to see the state data of the actor that closed out? 

Steven Howell
Controls and Instrumentation Engineer
Jacobs Technologies
NASA Johnson Space Center
0 Kudos
Message 6 of 10
(4,118 Views)

Steven,

 

have you been able to fix the problem? I am curious 🙂

 

Cheers

Oli

0 Kudos
Message 7 of 10
(4,099 Views)

Oli,

 

After I removed the class wire from the helper loop and used just the self enqueuer, I hadn't seen the problem return. I don't know if it was intermittent, or just my mistake. 


I can say that I have changed my development habits and don't wire the class wire to the helper loop anymore. Smiley Very Happy

Steven Howell
Controls and Instrumentation Engineer
Jacobs Technologies
NASA Johnson Space Center
0 Kudos
Message 8 of 10
(4,080 Views)

Thanks for the clarification Smiley Happy

0 Kudos
Message 9 of 10
(4,054 Views)

Good to know you sorted this out!

 

There's only one (dangerous) case where you can use the actor value wire in the helper loop: to read some of the actors private data that are not supposed to change after the actor is launched (basically an equivalent to the "const" keyword in C++). I say dangerous because it can cause confusion while reading the code (or for later modifications) without paying too much attention, being like "Hey I can actually access my actor's data in there so I'll just do it more!".

Other than that, forget it and use the enqueuer 🙂

Eric M. - Senior Software Engineer
Certified LabVIEW Architect - Certified LabVIEW Embedded Systems Developer - Certified LabWindows™/CVI Developer
Neosoft Technologies inc.

Message 10 of 10
(4,027 Views)