Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Actor Stopping/Error Handling

Solved!
Go to solution

I've recently started coding actor so please keep that in mind while reading this post. I just wanted to share my struggle with the framework.

 

Nearly every time I override the Handle Error.vi method, I end up breaking the stop mechanism on accident. I usually forget to put in case exceptions for 43 and 1608. I get that you want the ability for errors to stop an actor, but using errors as a stopping mechanism forces every single child compensate for that. That seems like a lot of extra cases when all I wanted to do was handle one code then let the parent handle the rest. Why tightly couple errors and the stopping mechanism?

 

The dissonance for me might stem from how I tend to use LVOOP. I tend to send up the framework in the parent such that the children only have to deal with specific implementation and need to have very little knowledge of the framework. Usually I make it hard for the child to accidentally interrupt this framework.

 

As a completely ignorant beginner: I guess I'm wondering why Stop wasn't an Actor Class boolean variable. You would set it using a  method. This method could be called in the Stop Message Do and possibly Handle Error if the developer chose. The actor core would just read that boolean at the end of each while loop iteration.

 

Now I'm going to stop yelling at the gods and digress. I do like the framework a lot. In the end, I was hoping to get some knowledge from this rant (either how people work with the handle error, or why it was done this way). Seems like ever time I alter/fight a framework, I end up regretting it in the end and seeing the wisdom built into the original.

Josh
Software is never really finished, it's just an acceptable level of broken
0 Kudos
Message 1 of 6
(7,491 Views)

First of all, you shouldn't have to do anything special for error code 43. Please read this post:

http://forums.ni.com/t5/Actor-Framework-Discussions/Handle-Error-vi/m-p/3403913#M1803

Make sure when you are overriding Handle Error.vi that you follow that general pattern.

 

I've got a much broader answer regarding the rest of your question and code 1608 but no time to type it right now. I'll try to get it written up later today.

Message 2 of 6
(7,475 Views)

@AristosQueue (NI) wrote:

First of all, you shouldn't have to do anything special for error code 43. Please read this post:

http://forums.ni.com/t5/Actor-Framework-Discussions/Handle-Error-vi/m-p/3403913#M1803

Make sure when you are overriding Handle Error.vi that you follow that general pattern.

 

I've got a much broader answer regarding the rest of your question and code 1608 but no time to type it right now. I'll try to get it written up later today.


I guess this might be a problem with how I've handled errors in the past with QMH. I tended to allow a thread/handler a chance to handle the error, then pass the error back to the main thread/handler. Eventually it would be displayed to the user. I tried to push this concept into actor framework and have nested actors report the error to their caller until landing with the root and being displayed. This means that my default was to let it live and continue on which is what interrupted the stop codes. Is it better to just let the nested actor die and try to recover?

 

What might have lead down this path was an unreliable parse-able serial stream from a particular device. I didn't want to bring things to a halt, but I wanted things to be handled and/or displayed in case it was important.

 

No rush, and thanks a lot for the response.

Josh
Software is never really finished, it's just an acceptable level of broken
0 Kudos
Message 3 of 6
(7,463 Views)
Solution
Accepted by topic author JW-JnJ

More time now. Let's do this...

 

Your instincts are good.

Your mistake was thinking that "Handle Error.vi" was meant to handle errors. 😉

 

That's a bit facetious, but I created the AF back in 2010, and in the years since, I've become more nuanced about error handling. When people use the term "error handling", they actually are referring to FIVE separate and somewhat independent things:

  1. Error Generation – creating an error value at the point that something goes wrong in the software. Generally the tools for this today are the Error Ring and "Error Cluster From Error Code.vi"
  2. Error Propagation – moving the error through the code: forking, merging, skipping execution of some nodes, etc. This gets into discussions of trying to aggregate multiple errors together, case structure, stopping loops when an error occurs, merging errors from parallel chunks of code, etc.
  3. Error Response – fixing or escalating errors. The tools involved in this are very similar to the tools used for Error Propagation (case structures, shift registers, etc), but the goal is different – rather than trying to get an error routed through the code, you're analyzing the error cluster and doing things like retrying the operation, clearing the error cluster, doing things if the code is a particular error code, translating error codes of a lower-level API for a higher-level API, etc.
  4. Error Display – showing the error to the user in some form/fashion. General Error Handler.vi is the primary form of this today.
  5. Error Logging – recording the error in a log file for later analysis. Similar to Error Display, but has some more interesting variations (recording as human readable or a more compact form, recording as localized or unlocalized [in a form that can be localized by a log reader later], etc.

The VI in the actor framework should be named "Propagate Error.vi". This VI is called after a method has already said, "I don't know how to react to this error, so I'm passing it to my caller." In Propagate Error, it is appropriate to

  • Clear the error
  • Change one error code to another error code and return it (which will kill the actor)
  • Add details to the error string and return it (which will kill the actor)
  • Send a separate message to the caller asking, "How do I proceed?", put the actor into some sort of holding pattern where it ignores all messages until it gets a response to its question, and then clear the error. (This might even be a time to use a synchronous Reply Msg message. Maybe.)

That last one is what you were asking about. It's a pretty advanced use case, but quite valuable. But if you do #4, notice that you are sending the error along to the caller in your own message. You aren't relying on the AF to propagate the error. If you return an error from Handle Error.vi, it means "Not only did my method not know how to deal with this situation, my whole actor didn't know how to deal with this situation, so the actor is going to go away now, and the message will go up to the caller (in the form of the Last Ack), and the caller can figure out what to do."

 

If you are in a parse method and you just want to display or log the error and continue operations, I suggest that you should NOT return that error from your method. Instead, that's part of the behavior of the actor's method: it sends a message to caller saying, "Caller, please display or log this error, whichever one you're doing." Then it clears the error and continue parsing or ends the method and the actor goes back to waiting for its next message. That's correctly handling the error.

 

I hope that clarifies things a bit. There's a much larger discussion here:

http://forums.ni.com/t5/Actor-Framework-Discussions/AF-error-reporting-and-handling/td-p/3386566

 

Now... why are we using error codes for stop?

 

Let me first say that I regret picking error code 43 (Cancel Error) for normal stop. I should have grabbed a unique error code. It has caused a few minor problems over the years. But setting that aside, I would still use error for stop if we redesigned from scratch today.

 

There's a few reasons. First of all, we have to have Handle Error (or its renamed equivalent) one way or the other -- we need the Do.vi to be able to return an error. If we don't, we have to make error a part of Actor's state, which bloats Actor needlessly. You are correct that "stop" could be a part of the Actor state, but it wouldn't be a Boolean. It would be an enum to specify "not stopping", "normal stop", or "emergency stop". But then people would want to include a reason or metadata about why it was stopping... which turns it into an error cluster, essentially, and we're right back where we started.

 

Really, stop isn't a state of the object, not really. It's just a halt of the state machine. That state machine could stop and start again, picking up right where it left off.

 

The more I looked at it -- and we tried multiple variations -- it made sense to have an error signal, and it made sense to have an external stop signal, and it really didn't make sense to have both.

 

Having said all that -- reasonable minds could easily disagree on this point! This is my opinion. If you design your own AF-like system (and many users have), you may make different choices.

Message 4 of 6
(7,455 Views)

Wow... wow. This response needs more kudos than I can give. Thanks for taking the time to detail all of that.

 


 Having said all that -- reasonable minds could easily disagree on this point! This is my opinion. If you design your own AF-like system (and many users have), you may make different choices.


It's funny because this notion doesn't even tempt me anymore. Like I said before, every time I fight/alter a framework I regret it later. Hence why I appreciate this post so much. This should hopefully help me reshape my preconceived notions.

 

So instead of relying on the underlying architecture to escalate then potentially display or log, I need to create a new channel for them to flow through.

Josh
Software is never really finished, it's just an acceptable level of broken
0 Kudos
Message 5 of 6
(7,434 Views)

Josh,

 

This is neither AF nor LabVIEW, but if you want to dig deeper on Error/Exception Handling you may want to read this white paper (especially the second part):

 

What it Really Takes to Handle Exceptional Conditions, Rebecca Wirfs-Brock, Addison-Wesley, 2003

 

Dmitry

 

Message 6 of 6
(7,412 Views)