SimpleActor
メッセージを自分自身に送信することで定期的なタスクを実行するActor ( ) がある非常に単純な例があります。メッセージは、アクターのコンストラクターでスケジュールされます。通常の場合 (つまり、障害がない場合)、すべて正常に動作します。
しかし、アクターが障害に対処しなければならない場合はどうでしょう。別のアクター ( SimpleActorWithFault
) がいます。このアクターには欠点がある可能性があります。この場合、例外をスローして自分で生成しています。障害が発生すると (つまり、SimpleActorWithFault
例外がスローされると)、自動的に再起動されます。ただし、この再起動により、アクタ内のスケジューラが台無しになり、例外として機能しなくなります。また、障害が急速に発生すると、予期しない動作がさらに発生します。
私の質問は、そのような場合に障害に対処するための好ましい方法は何ですか? Try
ブロックを使用して例外を処理できることを知っています。しかし、Try をスーパー クラスに配置できない別のアクターを拡張している場合や、例外的な障害がアクターで発生した場合はどうなるでしょうか。
import akka.actor.{Props, ActorLogging}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
import akka.actor.Actor
case object MessageA
case object MessageToSelf
class SimpleActor extends Actor with ActorLogging {
//schedule a message to self every second
context.system.scheduler.schedule(0 seconds, 1 seconds, self, MessageToSelf)
//keeps track of some internal state
var count: Int = 0
def receive: Receive = {
case MessageA => {
log.info("[SimpleActor] Got MessageA at %d".format(count))
}
case MessageToSelf => {
//update state and tell the world about its current state
count = count + 1
log.info("[SimpleActor] Got scheduled message at %d".format(count))
}
}
}
class SimpleActorWithFault extends Actor with ActorLogging {
//schedule a message to self every second
context.system.scheduler.schedule(0 seconds, 1 seconds, self, MessageToSelf)
var count: Int = 0
def receive: Receive = {
case MessageA => {
log.info("[SimpleActorWithFault] Got MessageA at %d".format(count))
}
case MessageToSelf => {
count = count + 1
log.info("[SimpleActorWithFault] Got scheduled message at %d".format(count))
//at some point generate a fault
if (count > 5) {
log.info("[SimpleActorWithFault] Going to throw an exception now %d".format(count))
throw new Exception("Excepttttttiooooooon")
}
}
}
}
object MainApp extends App {
implicit val akkaSystem = akka.actor.ActorSystem()
//Run the Actor without any faults or exceptions
akkaSystem.actorOf(Props(classOf[SimpleActor]))
//comment the above line and uncomment the following to run the actor with faults
//akkaSystem.actorOf(Props(classOf[SimpleActorWithFault]))
}