gpt4 book ai didi

scala - 处理 Akka actor 中的错误

转载 作者:行者123 更新时间:2023-12-04 06:19:05 26 4
gpt4 key购买 nike

我有一个非常简单的例子,我有一个 Actor ( SimpleActor ),它通过向自身发送消息来执行周期性任务。该消息在actor 的构造函数中被调度。在正常情况下(即没有故障),一切正常。

但是如果 Actor 必须处理错误呢?我有另一个 Actor ( SimpleActorWithFault )。这个 Actor 可能有缺点。在这种情况下,我自己通过抛出异常来生成一个。当发生故障(即 SimpleActorWithFault 抛出异常)时,它会自动重新启动。但是,这种重新启动会弄乱 Actor 内的调度程序,该程序不再作为异常(exception)运行。如果故障发生得足够快,它会产生更多意想不到的行为。

我的问题是在这种情况下处理故障的首选方法是什么? 我知道我可以使用 Try块来处理异常。但是,如果我要扩展另一个无法在父类(super class)中放置 Try 的角色,或者某些情况下我是 Actor 中发生的异常错误,该怎么办。

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]))

}

最佳答案

为了避免搞乱调度程序:

class SimpleActor extends Actor with ActorLogging {

private var cancellable: Option[Cancellable] = None

override def preStart() = {
//schedule a message to self every second
cancellable = Option(context.system.scheduler.schedule(0 seconds, 1 seconds, self, MessageToSelf))
}

override def postStop() = {
cancellable.foreach(_.cancel())
cancellable = None
}
...

正确处理异常(akka.actor.Status.Failure 用于在发送者使用 Ask 模式的情况下正确回答问题):
...
def receive: Receive = {
case MessageA => {
try {
log.info("[SimpleActor] Got MessageA at %d".format(count))
} catch {
case e: Exception =>
sender ! akka.actor.Status.Failure(e)
log.error(e.getMessage, e)
}
}
...

关于scala - 处理 Akka actor 中的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23109291/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com