繁体   English   中英

同步创建Akka演员

[英]Create Akka actor synchronously

我正在使用ActorSystem.actorOf(property, bla)创建一个演员。 问题在于,由于默认情况下Akka异步创建actor,所以我遇到了竞争条件。

有什么办法可以在Akka中同步创建演员吗?

在最简单的用例中,您可以简单地采用以下模式:

  1. preStart中,初始化一个长时间运行的异步任务
  2. 完成后,您会通过长时间运行的任务向自身发送一条消息
  3. 处理此结果时,可以初始化参与者的状态。

您还需要一个Subscribe消息:当actor收到检查其状态时,是否对其进行了初始化,则立即答复,如果没有,则将发送方附加到订阅方列表中。 处理初始化结果(3)时,您还通知所有订户。

trait ExpensiveThing
import MyActor._
class MyActor extends Actor {

  var expensiveThing : ExpensiveThing = null
  var initializationListeners:List[ActorRef] = List.empty


  def initializeExpensiveThing() : Future[ExpensiveThing]  = ???

  override def preStart(): Unit = {
    initializeExpensiveThing onSuccess  {
      case s => self ! InitializationDone(s)
    }

  }

  override def receive: Receive = {
    case InitializationDone(s) =>
      expensiveThing = s
      initializationListeners.foreach{ s => s ! Initialized }
    case SubscribeInitialization =>
      if(expensiveThing != null){
        sender ! Initialized
      }
      else {
        initializationListeners = sender() +: initializationListeners
      }

  }


}

object MyActor{
  case class InitializationDone(s:ExpensiveThing)

  case object SubscribeInitialization

  case object Initialized


}
object MyProgram {
  def doSomething(actorSystem:ActorSystem)  = {
    val actor = actorSystem.actorOf(Props(new MyActor))
    import akka.pattern.ask
    implicit val inizializationTimeout = new Timeout(100,TimeUnit.SECONDS)
    Await.result(actor ? SubscribeInitialization,Duration.Inf)
  }
}

笔记:

  1. 我强烈劝阻您不要使用Await.result,您应该只在将来使用flat模式时使用flatMap即可返回
  2. 应该使用context.become或Akka提供的FSM抽象来处理更复杂的生命周期。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM