Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Error 1556 while sending a message to other actor

Hello Everybody,

I am just starting with AF and after going through the basic AF introductory pages and example projects (cooler demo) I was very exited to port my existing (unfinished) project into the AF architecture.

Basically on this stage my system consists of several custom but identical bias cards plus a GUI to control these and displying up to date housekeeping info from the cards.

From the SW side the cards are represented as objects of the class "Bias Card", which inherits from a Generic Subsystem Class which in turn inherits from Actor. The GUI inherits from Generic Subsystem as well. There is no added functionality (methods/properties) on the Generic Subsdystem level at the moment, it was meant to be added in the future if necessary.

There is a launcher VI where I configure the HW communication etc. before starting the Actors.

When I perform an action on the GUI, a corresponding message to self queue is sent which causes the Actor core of the GUI to send the right message to the right Bias Card Actor to invoke the right method of this Actor. So far so good, this works OK.

However, part of the called Bias Card Actor method is to notify back the GUI actor of the change and this part ALWAYS generates an error:

Error 1556 occurred at In Place Element Structure in Actor Framework.lvlib:Message Priority Queue.lvclass:Priority Enqueue.vi:2960002

->GUI Actor Engine.lvclass:Switch Bias ON_OFF.vi

->Switch Bias ON_OFF_Msg.lvclass:Do.vi:3750001

->Actor Framework.lvlib:Actor.lvclass:Receive Message.vi:1040003

->Actor Framework.lvlib:Actor.lvclass:Actor Core.vi:5880002

->GUI Actor Engine.lvclass:Actor Core.vi:5880001

->Actor Framework.lvlib:Actor.lvclass:Actor.vi:6640007

->Actor Framework.lvlib:Actor.lvclass:Actor.vi.ACBRProxyCaller.D1800031

Possible reason(s):

LabVIEW:  The reference is invalid. This error might occur because the reference has been deleted.

The Enqueuer to the GUI Actor is part of the Bias Card Class data, which I have already tried to initialize in all sorts of diffrent ways, but apparently this queue is still invalid.

I have verified that the GUI methods work well if initiated from the louncher Vi using the GUI enqueuer obtained from the Launch Actor VI. It is just that they do not work when initiated from within the Bias Card class, as if the GUI queue reference were not passed correctly into the Card class data.

Below a couple of screenshots (I wanted to avoid posting the whole project at this moment as this is still in the process of being converted to AF and there are still many dependencies outside the folders, like controls etc.)

Thanks in advance for taking your time. I hope this will turn out to be my indolent exeprience with AF rather than some problem inside the AF.

Best Regards,

-mirode

Download All
0 Kudos
Message 1 of 19
(15,882 Views)

Are you sure, the Actor you're sending the message to is still alive? If you were able to send a previous message to the actor without an error, this message could have led to an error causing the Actor to stop and releasing its receive queue.

Message 2 of 19
(10,510 Views)

Hi Oli_Wachno,

Thanks for your post. I wanted to thoroughly check if this is the case so I have extended the GUI Message enqueue in the launcher VI to enqueue some test actions on the GUI (see screenshot -BTW, I realized I had a "presentation" error in the previous picture, though it had no impact on the actual problem).

The commands to the GUI can be enqueued without any problems from the launcher and I see the functionality is as desired. For me it means the GUI actor works.

The Bias Cards actors work as well, as I can invoke their methods (enqueue messages from the GUI to invoke their methods, to be precise).

The GUI Actor obviously stops after the mentioned error, so basically after the first invoke of any Bias card method, where the feedback to GUI causes an error. It means I am only able to execute one method of the Bias card actor and then my GUI stops, because of the error.Launcher VI corrected.png

0 Kudos
Message 3 of 19
(10,510 Views)

Helpfull hint: use the Monitored Actor for debugging. It'll show you which Actor Cores are alive very clearly

Regarding errors: an Actor will stop its core

  1. having received a stop message
  2. having received a message of an object type it "does not know" (default implementation, no "gracefull handling")
  3. after an error during message processing

I suspect cases 2. or 3. to be the case here. Can you check this?

Oli

0 Kudos
Message 4 of 19
(10,510 Views)

OK, thanks for drawing my attention to this interesting topic - I had a brief look at the posts and most likely use it at some point (if I decide to continue with AF in my work).

It looks like it (Monitored Actor) requires all the actors to inherit from this new class so it is a bit overhead but not much probably. For the time being, at least when it comes to debugging the active actors I can somehow help myself with the LV Task Manager, although it is not always convenient.

You are right in p.2 I could be sending messages that are not specified for a given actor and it could generate an error(?). I double checked this - I am definitely sending the correct messages, besides, if I use the same message VIs from the launcher level I experience no problems - as said above. There must be something in the reference that is not valid/not passed correctly/broken or whatever and it makes the sending of the message impossible.

Do I understand correctly the an actor has just one enqueuer that all of the other actors use to send messages to it, regardless of the actor hierarchy?

0 Kudos
Message 5 of 19
(10,510 Views)

mirode schrieb:

Do I understand correctly the an actor has just one enqueuer that all of the other actors use to send messages to it, regardless of the actor hierarchy?

Yes, you do, this is the default implementation.

The enqueuer is unique to the Actor. Every Actor instance has its own unique enqueuer. In fact, the enqueuer is created during launch of the Actor and its lifetime is directly coupled to the lifetime of the Actor. So if you mess up something during the execution of the Actor that causes it to stop, the enqueuer will be released and invalidating the reference to it. Trying to send messages on this invalid ref will result in an error.

Message 6 of 19
(10,510 Views)

To continue Oli_Wancho's point... this is why we encourage developers to respect the actor tree -- it limits these kind of lifetime issues.

You can design a nested actor so that it never shuts down on its own. Ever. If it reaches some sort of error state, it sends a message up to its caller that says, "I'm stuck and here's why." Then it just drops any new messages that come in until one of those messages tells it how to unstick itself. One of the ways it can get unstuck is to stop.

If you take that design, then your caller actor never gets an error when trying sending to a nested actor.

But it is often easier if the nested actor does get an error to just quit out. There is a timing gap where the nested actor could shut down and the caller actor doesn't know it yet. The caller might try sending in this gap, and thus might get a stale reference error, like the one you're getting. Your options here are:

a) Ignore errors that come when calling Send functions. Depending upon the design of your software, these are simply expected errors during shutdown and you just ignore them. This is the most common case.

b) Immediately upon getting one of these errors, put the caller into some sort of hold state and wait until the caller gets the Last Ack message, which will explain why the nested actor shut down, and then you can either shut down the caller, relaunch the nested actor, or decide to do something entirely different depending upon the reason for the shutdown.

We never implemented a full "safely break the connection" packet exchange for actors generally. You are free to do so in your actors as needed. Your GUI may need to have a full disconnect sequence. Are you familiar with TCP/IP? The disconnect sequence is something like:

a) nested sends messsage to caller of its intent to quit

b) caller receives notification and tells all of its process loops "stop sending to the nested actor"

c) caller waits for all process loops to acknowledge that they are no longer sending to the nested actor.

d) caller sends nested actor "you are now cleared to shut down"

e) nested receives the cleared-to-shut-down message, quits and sends the Last Ack.

That's a lot of back and forth, but it is what is needed to avoid any surprise errors in a disconnect when working with asynchronous systems. You can study different networking protocols to see if you need to develop one of these for your own work. If you implement one of these, then and only then do you know that errors from Send are truly the result of an actual transport layer failure (i.e. the network connection itself went away).

Message 7 of 19
(10,510 Views)

Hi mirode,

If I understand the problem correctly, the bias card claims it doesn't have a good reference to the GUI actor, not the opposite, is that correct? In that case it is the GUI actor that is closing unexpectedly, not the bias actors. To debug, override the stop core of the bias cards and the GUI actor and send a message to a log file somewhere (you can use my debug console if you want, or you can put breakpoints if you don't initialize a lot of actors). See what closes when and why. Does the GUI actor work well on its own? Does it close after one iteration automatically or something similar?

Are you sure that you send the action message to the bias after the GUI queue ref has arrived at the bias? keep in mind that in AF, sending messages in a certain order doesn't guarantee they will arrive in the same order. Probe the message VI shown above, is the GUI ref valid?

I think it would be better to either launch the bias cards from the GUI actor, and have the GUI actor keep the bias references and the bias actors communicate with the GUI actor using "read caller enqueuer", or keep all the refs in the launcher or another controller and communicate through that.

Good luck,

Danielle

"Wisdom comes from experience. Experience is often a result of lack of wisdom.”
― Terry Pratchett
Message 8 of 19
(10,510 Views)

Hi All,

Thank all of you for your patient and valuable suggestions. I will certainly utilize this useful information as I move forward with AF in this and subsequent projects.

I realized from the beginning, that my problem possesed the painfull risk of turning up to be a stupid one (although, as known from South Park, there are no stupid questions, just stupid people:) )

This was exactly the case, unfortunately, it was my fault, please be merciful and do not ask for details...;)

I can just say, I was indeed not passing the queue reference correctly into the class.

However, I noticed one additional thing, that was far from obvious for me before - After I had fixed my enqueuer problem I still faced a new one with the user event references. If I placed the create user event function in the louncher (as in the screenshot above), I was able to trigger these events over messages sent from the louncher, but was NOT able to do the same from within the GUI or Bias card classes (using exactly same VIs, and all VIs involved contained in the same project, so the same app instance?). Once I moved the Create Event into the GUI Actor everything was OK.

Thanks& Greetings,

-mirode

0 Kudos
Message 9 of 19
(10,510 Views)

I'm glad it's working for you mirode!

About the user event - In all the examples I saw, the create user event is in the pre launch init vi of the actor that should be registered for it.

Good luck!

Danielle

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