Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Actors appear to shut down, but still lock their libraries. Code included.

Solved!
Go to solution

Hello

I have run into a problem with the way I launch and/or stop my different actors - at least I assume this to be the problem.

The project has relatively few actors and I have tried to clear up the code as much as possible.

Actors:

Controller:

     Launches all other actors in a vi called Start all other actors

     Has Message Enqueuers for all actors so it can stop then in its stop core

MainUI:

     Has front panel visible and contains buttons/controls for testing functionality

     Has the Message Enqueuer to Logger

Logger:

     Has a vi called Log Message.vi that constructs a time stamped string with the wanted message and log level chosen by the MainUI controls.

     Has the Message Enqueuer to Logger Output File

Logger Output File:

     Actor Core is overridden and opens a file and then streams the log messages to it whenever Logger tells it to (by user event)

I launch the actors in the "Start all other actors.vi"  in the Controller in the following order (to simplify passing the enqueuers around). The Controller is launched by a normal vi called launcher.vi.

Another actor called TestActor is launched as the last actor if anyone wants to test something quickly. This actor is totally empty at the moment.

Logger Output File > Logger > MainUI > TestActor.

The problem:

The logging functionality works (i.e. the messages are being logged to the file correctly, the buttons work etc.), but after pressing my Stop button to quit the application all libraries are locked.

To debug this I tried to wrap the Logger Output File and Logger launch actor code in the Start all other actors.vi with a boolean to launch or not.

What I found out was that if only ONE of the two actors is launched then everything shuts down correctly. It doesn't matter which actor was excluded from the launch (except that the message logging buttons/controls won't work when Logger is not launched) - the code runs and shuts down as expected.

When both are launched all libraries are locked after quitting the program.

Suggestion if you want to help me debug:

Open Start all other actors.vi and test with only one of the two actors (Logger or Logger Output File) being launched, then test the opposite one being launched and finally test both being launched. When only Logger Output File is being launched you can still see that messages are being written to the log file (time stamped message saying "Log to file started")

When you run the code a file called logger.txt will be created in the WMS folder that you unzipped.


0 Kudos
Message 1 of 60
(18,841 Views)

Have you tried using the Monitored Actor? It will show you which Actor Cores are still alive and make debugging easier

0 Kudos
Message 2 of 60
(6,371 Views)

I have actually, but maybe I did not make it clear what I mean by "Actors appear to shut down". I have set all actors to show their frontpanel and when I press stop they all close their front panel, but the libraries are still locked.

So this is the same thing I found when using the Monitored Actor, everything appears to shut down (list of actors is empty), but libraries are still locked.

0 Kudos
Message 3 of 60
(6,371 Views)

AFAIK, only running Actor cores are displayed in the Monitord Actor's Panel.

Looking at Actor. VI, there are some VI that are executed after ActorCore.vi. Are you overriding any of those maybe causing a hang?

0 Kudos
Message 4 of 60
(6,371 Views)

Replying to myself here:

I seem to have found a solution (although I would swear I had tried this "solution" a multitude of times), but I am not sure why it works. Maybe someone can explain/elaborate for me.

This is the private data from the Logger actor

Logger private data.PNG

It has an array of Message Enqueuers (so it can auto index through multiple Logger Output enqueuers and call the specific overridden methods).

The apparent solution:

Force Logger to stop before stopping Logger Output File in the Stop Core of Controller.

I was sure I had tried every permutation of the order to stop each actor, but at the moment this seems to be working. However, I am not sure why I need to stop Logger before I stop Logger Output File.

If I stop Logger Output File then the enqueuer that Logger has in its private data is no longer valid. However, from what I understand the enqueuer is never used again unless I purposefully press the button that sends a message using this enqueuer? The Receive Message.vi and other behind the scenes stuff that might need this message enqueuer are stopped when I send normal stop to Logger Output File?

So why does Labview lock everything if I stop Logger Output File first thus making the enqueuer that Logger has invalid, even though I never use that enqueuer again? I guess Labview cannot be sure that I won't use it again or something?

0 Kudos
Message 5 of 60
(6,371 Views)

The only reason LV should be leaving things locked is because you are leaving things running. When you run your application and you think you stop everything but things are still locked, try quitting LabVIEW. Do you get a dialog that says that "quitting will abort running VIs"? I bet you do get such a dialog. Maybe you've found a bug -- it is definitely possible -- but the vast vast majority of the time that users report this issue, it is some VI in their code that is still running.

0 Kudos
Message 6 of 60
(6,371 Views)

Since NI does not like it when its beta users talk about the beta, perhaps AQ can try running this in 2014 and reporting the results himself.


___________________
Try to take over the world!
0 Kudos
Message 7 of 60
(6,371 Views)

Actually, I just realized that there are no repro steps. Kasper, can you provide a list of steps like:

  1. Open A.
  2. Run it.
  3. Do B.
  4. Do C.
  5. I expect to see D but actually see E.

This is important for such reports, because then it allows people to verify if there is an issue and where it is.


___________________
Try to take over the world!
0 Kudos
Message 8 of 60
(6,371 Views)

Sorry about the clarity of the original post (especially if you didn't read my self reply).

I believe that the reason all my libraries were locked was that I stopped an actor (invalidating its enqueuer) while another class still had that enqueuer in its private data and could potentially use it.

After reordering the way the actors are stopped, the libraries are no longer locked.

So it was probably an error on my part in the way I was sending the "Send Normal Stop" messages to the actors. Furthermore, I think I had forgotten that even if you send messages in the order A, B, C then they are not guarenteed to arrive in the same order. So perhaps my problem will resurface if my stop messages are not arriving in the order I expect them to.

If you still want to run the code for yourself (and playing around with the order in which actors are stopped) then follow these steps:

1. Open Launcher.vi and run it

2. Press the stop button labelled "Quit Program" on the front panel of MainUI

3. None of the libraries should be locked

4. If you check the logger.txt file in the directory of the project it should have a time stamped message verifying that the actor called Logger Output File did indeed run.

Change these things to make the libraries lock:


1. Open Start all other actors.vi in the Controller library

2. Change the boolean that is wired to case 1 of the stacked sequence from F to T (this will make the Logger actor launch)

3.Open Launcher.vi and run it

4. Write something in the string control and press the "send log request" button to write something to the logger.txt file

5. Press the stop button labelled "Quit Program" on the front panel of MainUI

6. All the libraries are locked


As described in an earlier reply or the OP; The actor called Logger has the Message Enqueuer of Logger Output File in its private data

0 Kudos
Message 9 of 60
(6,371 Views)

Kaspercj wrote:

I believe that the reason all my libraries were locked was that I stopped an actor (invalidating its enqueuer) while another class still had that enqueuer in its private data and could potentially use it.

That is incorrect. Holding onto the reference does not keep an actor running. The actor would quit anyway and the reference would simply go stale (if you tried to send messages, you'd get error code 1 for bad argument, just like for any queue).

The only way the VIs would stay reserved is if some VI in your system was still running.

The only way an actor would continue running is if it never got the stop message. If you had a caller actor stop and it never sent the stop message on to its nested actor, that would cause the problem.

If all your actors got the stop message, then it must be some other non-actor VI that you started running -- probably with the Asynch Call By Ref or with the Run VI method -- and forgot about.

0 Kudos
Message 10 of 60
(6,371 Views)