From 11:00 PM CDT Friday, May 10 – 02:30 PM CDT Saturday, May 11 (04:00 AM UTC – 07:30 PM UTC), 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: 

Stop Core.vi not executed...

Hi. I am working on my first Actor Framework project.

It has been going fine so far, but now I have encountered a problem.

In my project I have the root actor start five nested actors, where only two of the five nested actors override the Actor Core.vi. The two which overrides Actor Core.vi is:

- A communication actor which is polling a COM port to check if the machine we work on is connected

- A GUI actor.

The communication actor inherits directly from Actror.lvclass.

The GUI actor is actiually two diffeerent actors which is never started at the same time. One is use for service operations on special service stations and the other for more common operations. But they share some common features, and thus I decided to make a GUI base class which inherits  from Actror.lvclass. The two GUI actors then inherits  from my GUI base class.  I have overridden the Stop Core.vi for all the actor classes in which I have overridden the Actor Core.vi. So far so good.

Now the problem I have encountered is this:

When i start my application with one the two GUI actors and the communication actor running, and I attempt to close the application by stopping the root actor or one of the GUI actors (the result is the same), the communication actor dos not receive the stop message and thus its Stop Core.vi is never called. If however I do not start a GUI actor and I stop the application by closing the root actor, it works fine.

I should add that at first we only had one GUI actor, and at that time the GUI actor inherited directly from Actror.lvclass. That setup worked just fine with at shut down. It is only after I have refactored the GUI actor(s) to have this GUI base class that it stopped working.

I suppose it is a simple mistake I have done, but since I am new to the Actor Framework, I can't seem to see what went wrong.

Cheers

Jens.

Best regards
Jens Christian Andersen.
CLA, CTA, CPI
0 Kudos
Message 1 of 10
(5,762 Views)

Hi Jens,

you have to make sure, that all actors receive a stop message. An actor invoking subactors should provide also a decent way of stopping its subactors.

Which actor is supoosed to stop your communication actor? If it is the communication actors, where do they differ? Also note, that dynamic dispatching sometimes can play nice tricks on you

Oli

0 Kudos
Message 2 of 10
(4,380 Views)

Maybe there is a Call Parent missing somewhere?

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

Jens,

Stopping nested actors is optionally built in, but there are some things to be aware of.

1. When launching a nested actor you can leave the Auto-stop? (T) connector unwired and then it will add the nested actor's enqueuer to an array of enqueuers that will all receive a stop message when the parent stops.

2. You can wire a False into the Auto-stop? connector and then you are responsible for stopping the nested actor. Prior to 2014 this was the way it worked. Then you would be responsible for storing the enqueuer of the nested actor and deciding when to stop it. Generally speaking you would add an enqueuer to the private data of the root actor and then bundle by name the enqueuer from the launch method. In Stop Core you would send a Normal or Emergency Stop to the nested actor. I still like to do this when I am controlling lifetimes.

3. If you stop a nested actor with a "Normal Stop" message it returns a last ack that doesn't have an error. So, if you stop the program from a nested actor you need to exit with an error code that causes Handle Last Ack to evaluate to an error and then stop you root actor which will then stop your other nested actors.

Casey

Casey Lamers


Phoenix, LLC


casey.lamers@phoenixwi.com


CLA, LabVIEW Champion


Check Out the Software Engineering Processes, Architecture, and Design track at NIWeek. 2018 I guarantee you will learn things you can use daily! I will be presenting!

Message 4 of 10
(4,380 Views)

Jens,

I'm working on a very similar project where I have RS232 sensors which I want to poll, log and plot on a GUI. Although I don't have a great answer for your issue, I'll point you towards something I found yesterday-> Monitored Actors.

https://lavag.org/topic/17056-monitoring-actors/

You basically add the library to your project and have your Actors inherit from the Monitored Actor.lvclass instead of Actor.lvclass and at runtime it provides a really nice, additional interface allowing you to monitor, kill and even debug actors that are misbehaving. This has made it far less painful and you don't have to close LabVIEW everytime an Actor gets stuck in a loop.

Cheers,

Winston

Message 5 of 10
(4,380 Views)

Oli_Wachno wrote:

Maybe there is a Call Parent missing somewhere?

Unlikely. The "Must Call Parent" flag is on the Actor Core.vi, and that is sufficient to guarantee that Stop Core gets invoked. Stop Core also has "Must Call Parent." I can't think of any way this could ever be the problem (other than LV itself having a bug, but that seems unlikely in a code path this heavily traveled).

0 Kudos
Message 6 of 10
(4,380 Views)

Hi,

Without actually seeing your code, I understood that closing the GUI actor should send a message to the root actor (or maybe you use the GUI actor's last ack instead) and the root actor should then send a stop message to itself to stop all its nested actors. Is this how you are handling the GUI stop?

Also, are you using LV14 with "Launch nested actor" with default "stop nested" to "true" or are you using another method?

Thanks,

Danielle

"Wisdom comes from experience. Experience is often a result of lack of wisdom.”
― Terry Pratchett
0 Kudos
Message 7 of 10
(4,380 Views)

Hi Danielle.

Yes you understood it correctly, and I am using LV2014 with "Launch nested actor" with default "stop nested" to "true".

After spending a lot of time debugging I found out that it all came down to a race condition at application startup.

It turned out that my communication actor started producing messages for the GUI actor (using the root actor as relay) before the GUI actor core was ready. This would normally not be a problem in the Actor Framework, but in my case I need to get some data (the connection state) from the message Do.vi in to the UI data, which is all handled in an event structure in the GUI actor core. So I generate a User Event in the message Do.vi which is handled by the event structure in GUI actor core. But the race condition meant that the first message could fire the event before it got registered with the event structure which was suppose to handle it.

I do not know how this could have broken the messaging with the communication actor all together, but when I got this fixed the problem disappeared. I made a "GUI_Ready" message, which the GUI actor must send to the root actor after it has registered it User Events. The root actor then sends relevant messages to other actors which needs to wait for the GUI to be ready....

After I did this extra "debug review" I am not sure that I like the setup, but it works. Possibly I went down a wrong track when I decided to use User Events to move data in to my GUI data handling in the GUI actor, but it seemed like a reasonable and straight forward approach at the time.

But in general, how do you (all of you) handle issues like this, and are we not missing some mechanism in the Actor Framework to synchronize the execution of actor cores at custom points of execution, or have I missed some feature which is already present in the implementation?

Cheers

Jens.

Best regards
Jens Christian Andersen.
CLA, CTA, CPI
Message 8 of 10
(4,380 Views)

J.C._Andersen wrote:

are we not missing some mechanism in the Actor Framework to synchronize the execution of actor cores at custom points of execution, or have I missed some feature which is already present in the implementation?

The primary aim of the AF is to not need synchronization between any actor cores. Trying to build such sync points proved so nasty to get right, it's one of the things that drove me to investigate actor programming in the first place.

> when I decided to use User Events to move data in to my GUI data handling in the GUI actor

Assuming I read this right, that's the recommended solution. You have a single GUI actor and you need to pass information from the message handling loop to the UI loop in your Actor Core, right? If that's correct, then firing user events is exactly the right way to do this.

Where you may have gone wrong -- you create the user event on the block diagram of Actor Core, right? You need to make sure that the Register For Event node is executed before the Call Parent node. Just serialize the calls with the error cluster and you should be fine.

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

Yes, you read it right that is what I am doing.

I am creating my user event in a sub VI in the Pre Launch Init.vi and storing the ref. in a type def. cluster in my GUI actor class. I then do the registration of the User Events on the block diagram of the Actor Core, and that part is serialized as you describe.

GUI_Actor_Core_Block_Diagram.png

As you can see from the image I register one set of events from my child GUI class and one set from my parent GUI class.

And of cause it makes sense that the actor cannot receive or process any messages until the message handling loop of the parent is running. I totally get that now.

But this gets me more worried, because it means that I may not have found the original problem after all.

I have not been able to able to reproduce the problem since I created that extra "GUI Ready" message.

In the next picture you see a screen shot of my other GUI actor (selection of GUI actor is done offline in an ini file).

GUI_Actor_Core_Block_Diagram2.png

Here I have added a sub VI which sends the "GUI Ready" message. As I described in an earlier post this keeps the communication actor from attempting to sending messages to the GUI actor until the "GUI Ready" message is received. I may need to go back and undo my changes one by one, to see if I can reproduce the problem.

Cheers

Jens.

Best regards
Jens Christian Andersen.
CLA, CTA, CPI
0 Kudos
Message 10 of 10
(4,380 Views)