I'm new to the actor model and I wonder how runtime errors should be handled.
Suppose actor catches exception, what should it do then?
I definitely want the sender to be notified of any errors, so, at least sender could log the errors.
Should all the response messages contain status field or should there exist XXXErrorMessage class for every response message in my application?
What are best practices for error handling in actor model?
You should google "erlang supervisor design", since the Actor model was mostly paved in erlang. Then you can apply the described knowledge with Akka actors (which is becoming standard actor lib in Scala 2.10). Also read the above commented akka docs on supervision and fault tolerance.
Alternatively, you might choose not to use Actors, but Futures instead, which are easier to compose. Then you will have Future[Either[E, A]] types, which you can treat as a combined EitherT[Future, E, A] monad type using scalaz + akkaz and use it in for comprehensions for example.
I would go with Actors if I expect a lot of failure, need to restart and retry things, having to encapsulate mutable state, etc. If you don't need these, you may fall back to Futures and have a better sleep.
Related
In my project, we often use stateless actors. Reason is that we want to use these actors for fire-and-forget messages.
This provides us a quick way to perform an async task without creating and managing futures ourselves.
This works very well, but one of the issues is that testing this stuff is really hard. I wonder how can I write the test case for this.
One obvious thought is that at the end of the code execution I can do sender ! EmptySuccess and then the test cases could use the ask pattern to look whether they got the EmptySuccess or not.
The problem is that in production all the code will use ! on the actor reference and therefore we may end up with lots of dead letter messages which may pollute our logs (because the senders don't really wait for receiving the answer from the actor).
Edit: We don't want to switch to futures as of now. Reason is that this is legacy code and if we cannot turtle our future all the way down, because this will mean a lot of code change.
The best solution for this is likely in the akka testkit.
http://doc.akka.io/docs/akka/current/scala/testing.html
If you just want to test that an actor is sending messages to another actor and that they are received, send messages to a test probe. You can then inspect that probe and do really useful things like ensure it received x number of messages in n seconds or use should matchers on the messages in the probe
I would like to use an actor to synchronize access to a pool of objects. The actor would manage the objects in the pool including their state (busy v.s. free to allocate). When asked by non-actor code, it would return an object from the pool once available. Thus the calling code has an abstraction for obtaining an object to work with.
To get this kind of abstraction, I need the actor to be able to respond to its message senders' ask messages with the object the actor is allocating to them. Can this be accomplished and would it be resource intensive to pass a whole object via a message?
There is nothing wrong in returning future that will be completed later, by actor.
Keep an eye on this matter, however: will you complete the future with some mutable internal actor state or not?
If the answer is no - it is ok and there is nothing you should worry about.
If the answer is yes - you'll have to take care of synchronization, since actor/external code may mutate this state in different threads (which, kind of defeats the purpose of using actors).
Otherwise it is legit.
BTW, this is not something that is specific to futures only. You have to follow this for any message you send from actor.
UPDATE: extending my answer to address OP's comment.
Question was primarily about returning an object that's not an actor, from an actor, not just about the scenario... not sure if this answer relates to just that... an object can be much heavier than just a "regular" message... unless Akka passes a message in a way equivalent to a reference / interning.
There is no special requirements about "heaviness" of the message in akka and in general it can be any object (you can infer this from the fact that Any is used for the type of the message instead of some akka-defined message class/trait with set of defined limitations).
Of course, you have to treat specially situations when messages should be persisted or sent to remote host, but this is kind of special case. In this scenario you have to ensure that serialization is handled properly.
Anyway, if the message (object) does not leave boundaries of the same jvm - it is ok for object to hold any amount of state.
Akka has deprecated actorFor in favor of actorSelection. The former returns an ActorRef while the latter returns an ActorSelection which could be a collection of ActorRefs.
When migrating from actorFor to actorSelection, you have a couple of optoins:
Option 1: Both ActorSelection and ActorRef have a tell method, so you could almost exchange actorSelection for actorFor (this is not always true - ask is not the same and actorSelection could point to multiple ActorRefs) so long as there is only one actor for that selection and you are only telling the actor.
Option 2: Get an ActorRef from the ActorSelection. This can be done using either Identify (which involves a couple more messages) or resolveOne (which involves a Future).
In Option 1, what kind of overhead does ActorSelection add compared to the ActorRef from actorFor?
Is there a better option than the ones listed above?
There is overhead for using ActorSelection versus ActorRef, specifically:
It is not as performant as with ActorRef, since it has to traverse the
hierarchy of actors in the path. If you use remote sends the actor
selection traversal will unlikely be the bottleneck, but you have to
verify that for your specific usage. We optimized ActorSelection in
2.3.x, so it will be faster when you update to that version.
Source: Post by Patrik Nordwall on the Akka User list.
In the option 1, the overhead is that the message might be sent to multiple actors instead of just one. If you use wildcards, the actor system will have to identify all the actors matching the actor selection string (some of which are possibly remote), so this might end up being a slower than sending a message to just one specific actor.
However, as long as you don't use wildcards with actorSelection, the ActorSelection object will refer to at most one actor.
If you want to use the ask pattern, you have to first obtain the ActorRef using the Identify message - there is no better way that option 2.
I'm just starting to learn Akka Actors in Scala. My understanding is that messages received by an Actor are queued in an Actor's mailbox, and processed one at a time. By processing messages one at a time, concurrency issues (race conditions, deadlocks) are mitigated.
But what happens if the Actor creates a future to do the work associated with a message? Since the future is async, the Actor could begin processing the next several messages while the future associated with the prior message is still running. Wouldn't this potentially create race conditions? How can one safely use futures within an Actor's receive() method to do long running tasks?
The safest way to use futures within an actor is to only ever use pipeTo on the future and send its result as a message to an actor (possibly the same actor).
import akka.pattern.pipe
object MyActor {
def doItAsynchronously(implicit ec: ExecutionContext): Future[DoItResult] = {
/* ... */
}
}
class MyActor extends Actor {
import MyActor._
import context.dispatcher
def receive = {
case DoIt =>
doItAsynchronously.pipeTo(self)
case DoItResult =>
// Got a result from doing it
}
}
This ensures that you won't mutate any state within the actor.
Remember two things
The notion behind the term Future(a special actor) is that we can create an actor for any result while it(the result) is still being computed, started or finished but we can't have an address for that special actor or future.
Suppose I want to buy something (my result is buying something, and the process it to initiate steps to start buying procedure) we can create an actor for the result (buy) but if there is any problem and we can't buy the thing we will have an exception instead of the result.
Now how the above two things fit is explained below-
Say we need to compute the factorial of 1 billion we may think that it will take a lot of time to compute but we get the Future immediately it will not take time to produce the Future (" Since the future is async, the Actor could begin processing the next several messages while the future associated with the prior message is still running."). Next, we can pass this future, store it and assign it.
Hope so you understand what I'm trying to say.
Src : https://www.brianstorti.com/the-actor-model/
If you need to mutate state in futures without blocking incoming messages you might want to reconsider redesigning your actor model. I would introduce separate actors for each task you would use those futures on. After all, an actor's main task is to maintain its state without letting it escape thus providing safe concurrency. Define an actor for those long running task whose responsibility is only to take care of that.
Instead of taking care of the state manually you might want to consider using akka's FSM so you get a much cleaner picture of what changes when. I presonally prefer this approach to ugly variables when I'm dealing with more complex systems.
I found there is also an Akka actor model, so I am wondering what's the difference between the Akka's Actor and Scala's Actor model?
Well, there isn't. There is just Actor model, and Akka actors and Scala actors are two implementations of that model.
All Actor model says that your concurrency primitives are actors, which can:
receive a message and decide what to do next depending on the content of the message, including:
send messages to any actors they know about
create new actors
and provides certain guarantees, e.g.:
any actor will only handle a single message at a time
messages sent by actor X to actor Y will arrive in the order thay were sent
There is no difference between Scala and Akka actors on this level.
For differences in what they can do, see Different Scala Actor Implementations Overview. The biggest one, for me, is that Akka supports supervisors and ActorRegistry.
There is also a historical answer. The creators of Scala thought there should be an actor framework. Jonas Bonér tried it out, but was not completely satisfied so he started working on a new - which evolved into Akka. However, the Scala people thought it was better than their own - so at Jfokus 2011 they announced that Akka was to become the standard actor framework of Scala. However, that migration will take some time.
This depends a little on what you mean with "model" - you can either refer to the "execution model" or the "programming model" (and perhaps other models as well).
For execution models, there are basically two: thread-based or event-based. The Scala standard actor library contains both. The thread-based uses one thread for each actor, whereas the event-based uses a thread-pool. The former is more intuitive to understand, the latter is more efficient. Akka is built on the event-based model.
For programming model, there is a big difference between the scala standard library and Akka. In the scala standard library, you basically implement the "run" method - and if you want to wait for an incoming message, you get yourself into a waiting state (by calling "receive" or "react"). So, the programming model follow the "thread-metaphor". However, in Akka, the programming metaphor is that you implement a few life-cycle methods - but the "run"-method is written inside the framework. It actually turns out that this programming model works a lot better with the event-based execution model as well.
If you are interested in the different execution models and programming models of scala standard actors I have written a few posts on the issue.