Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle exceptions within the actor?

Tags:

c#

akka.net

Is there a standard pattern to deal with exceptions within actors in Akka.NET?

I saw some patterns to create supervisors, but it seems the SupervisorStrategy is a way to deal with things that cannot be resolved by the actor.

I have an actor that receives lots of data and needs to store it in an external server. The external database may be unreachable. If it is, the server may be restarting or the network may be down. I don't need to restart the actor or anything, I just want to notify the sender with some information about what is happening, so he can persist the message on disk and reschedule for later.

The sender is not a parent of this actor connecting to the database. Should I create a supervisor just to handle this as well? Or should I encapsulate my receive handlers in try/catch blocks and just use Tell to notify the senders a with a custom response as if it was a normal message?

I know there is a Failure class, but I'm not sure if I'm suppose to use that for this situation.

like image 494
Natan Avatar asked Feb 07 '15 21:02

Natan


People also ask

How do you handle exceptions in the classroom?

The try-catch is the simplest method of handling exceptions. Put the code you want to run in the try block, and any Java exceptions that the code throws are caught by one or more catch blocks. This method will catch any type of Java exceptions that get thrown.

How do you stop an actor?

ActorContext is used to stop child actor and ActorSystem is used to stop top level Actor. The actual termination of the actor is performed asynchronously. There are some other methods available in Akka, which are used to stop Actor. Some of which are PoisonPill, terminate() and gracefulStop() are used to stop Actor.


1 Answers

Yes there is. First of all, always delegate dangerous work to child actors, give them all your knifes, flame thrower and such. if they crash and burn, your state is still intact and you can spawn new children.

So for the unreachable database example; Spin up a DB-communication actor. You can then let this actor have two states, DB up and DB down, this can be modeled as an FSM or using Become/Unbecome.

So when a message arrives and requesting a DB query, if things blow up, the DB communicator actor puts it self into DB-Down state. If any query is received in DB-Down state, you can immediately respond with a Failure event.

So how do we go from DB-Down to to DB-Up again? The DB-Communicator actor can ping it self using ScheduleOnce, e.g. pass it self a "CheckDBStatus" message every x seconds. When the CheckDBStatus message is received, you check if DB is up again, and if so, you revert back to DB-Up state.

This way, you will not flood your DB in scenarios where it is unable to respond due to high load, adding more load in that case will only make things worse. So this kind of circuit breaker will prevent that from happening.

So in short:

In DB-Up state:

If a DBQuery message is received, try to run the query, and send back the response. if things blow up, go directly to DB-Down state and respond with a failure event.

In DB-Down state: if a DBQuery message is received, respond with a Failure event directly w/o touching the DB. Ping yourself every x seconds to see if DB is up, and revert to DB-Up state if possible.

In this scenario, you would not use any supervisor to transit the state, normal try/catch would be enough to deal with this.

Hope this clear things up.

like image 113
Roger Johansson Avatar answered Sep 19 '22 06:09

Roger Johansson