postRestart和preRestart方法没有在akka actots中调用

时间:2016-06-03 07:52:36

标签: scala akka actor lifecycle akka-supervision

我关注this tutorial这是我的代码

case class ArtGroupDeleteFromES (uuidList:List[String]) 
class ArtGroupDeleteESActor extends Actor{
val log = LoggerFactory.getLogger(this.getClass)
    override def preStart() {
      log.debug("preStart  Starting ArtGroupDeleteESActor instance hashcode # {}",
       this.hashCode())
      }

    override def postStop() {
      log.debug("postStop Stopping ArtGroupDeleteESActor instance hashcode # {}",
       this.hashCode())
      }

    override def preRestart(reason: Throwable, message: Option[Any]) {
      log.debug("I am restarting")
      log.debug("ArtGroupDeleteESActor: preRestart")
      log.debug(s" MESSAGE: ${message.getOrElse("")}")
      log.debug(s" REASON: ${reason.getMessage}")
      super.preRestart(reason, message)
      }

    override def postRestart(reason: Throwable) {
      log.debug("restart completed!")
      log.debug("ArtGroupDeleteESActor: postRestart")
      log.debug(s" REASON: ${reason.getMessage}")
      super.postRestart(reason)
      }
def receive = {
  case ArtGroupDeleteFromES(uuidList) =>
 throw new Exception("Booom")
  sender ! true
   }
  case  message => 
    log.warn("Received unknown message: {}", message)
    unhandled(message)
 }

}

以下是我如何向这位演员发送消息

class ArtGroupDeletionActor extends Actor{

  val log = LoggerFactory.getLogger(this.getClass)
 override val supervisorStrategy = OneForOneStrategy(
                                    maxNrOfRetries = 10, withinTimeRange = 10 seconds) {
    case _:Exception => Restart
  }
 val artGroupDeleteESActor=context.actorOf(Props[ArtGroupDeleteESActor]
      .withDispatcher("akka.actor.ArtGroupDeleteESActor-dispatcher")
      ,name = "ArtGroupDeleteESActor")

   def receive = {

    case DeleteArtGroup(uuidList) =>
      val future1  = ask(artGroupDeleteESActor, ArtGroupDeleteFromES(uuidList)).mapTo[Boolean]
      var isDeletedfromES = Await.result(future1, timeout.duration)
    case message =>
      log.warn("Unhandled message received : {}", message)
      unhandled(message)
  }
}

object test extends App{
 val artGroupDeletionActor=system.actorOf(Props[ArtGroupDeletionActor]
      .withDispatcher("akka.actor.ArtGroupDeletionActor-dispatcher")
      ,name = "ArtGroupDeletionActor")
     artGroupDeletionActor ! DeleteArtGroup(List("123"))
}

PostRestart()和preRestart()方法没有调用,但preStart()和postStop()被调用,请指导我在哪里做错了

1 个答案:

答案 0 :(得分:3)

(为简单起见,我将从现在开始称呼您的演员ParentChild

这里发生的事情是,当Child.receive内发生异常时,它不会向Parent发送响应,而是演员系统发送一些监督策略的控制指令。但是,Parent上的Await已被future1阻止等待timeout的完成,这只会在TimeoutException超过之后发生,然后又会Parent.receiveParentChild内抛出,杀死(重启)deadLetters actor本身,因此Child中异常的监督消息传递给 val future1 = ask(artGroupDeleteESActor, ArtGroupDeleteFromES(uuidList)).mapTo[Boolean] var isDeletedfromES = Await.result(future1, timeout.duration) ,永远不会重新启动onComplete 1}}。

你永远不应该永远阻止一个演员,所以这是不正确的:

self

相反,您必须使用某种消息标识来区分并发环境中的一个回复,或者将case class ArtGroupDeleteFromES(id: Long, uuidList: List[String]) case class ArtGroupDeleteFromESResult(id: Long, success: Boolean) class Parent extends Actor { override val supervisionStrategy = ... var msgId = 0L var pendingRequesters = Map.empty[Long, ActorRef] val child = context.actorOf(Props[Child]) def nextId = { msgId += 1 msgId } def receive = { case DeleteArtGroup(uuidList) => val id = nextId pendingRequesters += id -> sender() // store a reference to the sender so that you can send it a message when everything completes child ! DeleteArtGroupFromES(nextId, uuidList) case ArtGroupDeleteFromESResult(id, success) => // process result... pendingRequesters(id) ! "done" pendingRequesters -= id } } 添加到Future并在闭包中向case class ArtGroupDeleteFromES(uuidList: List[String]) case class ArtGroupDeleteFromESResult(replyTo: ActorRef, success: Boolean) class Parent extends Actor { override val supervisionStrategy = ... val child = context.actorOf(Props[Child]) def receive = { case DeleteArtGroup(uuidList) => val requester = sender() // when the future completes, sender may have already changed, so you need to remember it (child ? DeleteArtGroupFromES(uuidList)).onComplete { case Success(success) => self ! ArtGroupDeleteFromESResult(requester, success) case Failure(e) => log.warn("Could not delete...", e) self ! ArtGroupDeleteFromESResult(requester, success = false) } } 发送消息(注意:除了发送消息之外没有其他逻辑应该在封闭内部执行到未来!)。

所以,选项A:

{
  "development": {
    "username": "******",
    "password": "******",
    "database": "******",
    "host": "127.0.0.1",
    "dialect": "mysql",
    "timezone": "Europe/Warsaw"
  },
  "production": {
  }
}

选项B:

 export interface OverlayViewOptions {
   position: LatLng|LatLngLiteral;
   map?: GoogleMap;
   draggable?: boolean;
   objectId?: string;
}