如何应对Akka儿童演员的长时间初始化? [英] How to deal with long initialization of an Akka child actor?

查看:85
本文介绍了如何应对Akka儿童演员的长时间初始化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个演员,它创建一个子演员来执行一些冗长的计算。



问题是子actor的初始化需要花费几秒钟,并且父actor发送给孩子的所有消息都将在其间创建并完全初始化。 。



这是我使用的代码的逻辑:

  class ChildActor扩展Actor {
val tagger = IntializeTagger(...)//这需要几秒钟才能完成

def接收= {
case Tag(text) =>发件人! tagger.tag(text)
case hello => println( H​​ello)
case _ => println(未知消息)
}
}

类ParentActor扩展Actor {
val child = context.ActorOf(Props [ChildActor],name = childactor )

//以下两条消息似乎迷失了
孩子! 你好
孩子! Tag(这是我的示例文本)

def接收= {
...
}
}

我该如何解决这个问题?是否可以让父演员等到孩子被完全初始化?我将使用子actor进行路由,并可能在远程actor系统上使用。



EDIT



按照drexin的建议,我将代码更改为:

  class ChildActor扩展Actor {
var tagger: Tagger = _

覆盖def preStart()= {
tagger = IntializeTagger(...)//这需要几秒钟才能完成
}

def receive = {
case Tag(text)=>发件人! tagger.tag(text)
case hello => println( H​​ello)
case _ => println(未知消息)
}
}

类ParentActor扩展Actor {
var子代:ActorRef = _

覆盖def preStart()= {
child = context.ActorOf(Props [ChildActor],name = childactor)

//添加
// Thread.sleep(5000 )
//这里的消息没有问题

//硬编码等待5秒钟的
//下面的两条消息似乎让
的孩子迷路了! 你好
孩子! Tag(这是我的示例文本)
}

def接收= {
...
}
}

但问题仍然存在。我想念什么?

解决方案

不要在构造函数中初始化 tagger preStart 钩子,这样,当参与者准备好时,消息将被收集在消息框中并交付。



编辑



您应该在 ParentActor 类,因为在初始化 ParentActor 之前,如果 ChildActor 会做出响应,则会遇到同样的问题。 / p>

edit2



我创建了一个简单的示例,但无法重现您的问题。以下代码可以很好地工作:

  import akka.actor._ 

case class Tag(x: String)

类ChildActor扩展Actor {
type Tagger = String =>字符串
var标记器:Tagger = _

覆盖def preStart()= {
标记=(x:字符串)=> x + @ tagged //这需要花费几秒钟来完成
Thread.sleep(2000)//模拟初始化Tagger
}花费的时间

def receive = {
case Tag(text)=>发件人! tagger(text)
case hello => println( H​​ello)
case _ => println(未知消息)
}
}

类ParentActor扩展Actor {
var子代:ActorRef = _

覆盖def preStart()= {
child = context.actorOf(Props [ChildActor],name = childactor)

//添加
// Thread.sleep(5000 )
//这里的消息没有问题

//硬编码等待5秒钟的
//下面的两条消息似乎让
的孩子迷路了! 你好
孩子! Tag(这是我的示例文本)
}

def接收= {
case x => println(x)
}
}

对象主要扩展应用{{b
$ b val system = ActorSystem( MySystem)

system.actorOf(Props [ParentActor])
}

输出为:

  [info]正在运行主要
您好
这是我的示例text @ tagged


I have an actor which creates a child actor to perform some lengthy computations.

The problem is that the initialization of the child actor takes a few seconds and all messages that the parent actor sends to the child between it is created and gets fully initialized are dropped.

This is the logic of the code that I am using:

class ChildActor extends Actor {
  val tagger = IntializeTagger(...) // this takes a few seconds to complete

  def receive = {
    case Tag(text) => sender ! tagger.tag(text)
    case "hello" => println("Hello")
    case _ => println("Unknown message")
  }
}

class ParentActor extends Actor {
  val child = context.ActorOf(Props[ChildActor], name = "childactor")

  // the below two messages seem to get lost
  child ! "hello"
  child ! Tag("This is my sample text")

  def receive = {
     ...
  }
}

How could I get around that problem? Is it possible to make the parent actor wait until the child is fully initialized? I will be using the child actor with routing and possibly on remote actor systems.

EDIT

Following drexin's advice I have change my code into:

class ChildActor extends Actor {
  var tagger: Tagger = _

  override def preStart() = {
    tagger = IntializeTagger(...) // this takes a few seconds to complete
  }

  def receive = {
    case Tag(text) => sender ! tagger.tag(text)
    case "hello" => println("Hello")
    case _ => println("Unknown message")
  }
}

class ParentActor extends Actor {
  var child: ActorRef = _

  override def preStart() = {
    child = context.ActorOf(Props[ChildActor], name = "childactor")

    // When I add
    // Thread.sleep(5000)
    // here messages are processed without problems

    // wihout hardcoding the 5 seconds waiting 
    // the below two messages seem to get lost
    child ! "hello"
    child ! Tag("This is my sample text")
  }

  def receive = {
     ...
  }
}

but the problem remains. What am I missing?

解决方案

Don't initialize the tagger in the constructor, but in the preStart hook, this way the messages will be collected in the message box and delivered, when the actor is ready.

edit:

You should do the same for the actor creation in your ParentActor class, because you would have the same problem, if the ChildActor would respond, before the ParentActor is initialized.

edit2:

I created a simple example, but I was not able to reproduce your problems. Following code works perfectly fine:

import akka.actor._

case class Tag(x: String)

class ChildActor extends Actor {
  type Tagger = String => String
  var tagger: Tagger = _

  override def preStart() = {
    tagger = (x: String) => x+"@tagged" // this takes a few seconds to complete
    Thread.sleep(2000) // simulate time taken to initialize Tagger
  }

  def receive = {
    case Tag(text) => sender ! tagger(text)
    case "hello" => println("Hello")
    case _ => println("Unknown message")
  }
}

class ParentActor extends Actor {
  var child: ActorRef = _

  override def preStart() = {
    child = context.actorOf(Props[ChildActor], name = "childactor")

    // When I add
    // Thread.sleep(5000)
    // here messages are processed without problems

    // wihout hardcoding the 5 seconds waiting 
    // the below two messages seem to get lost
    child ! "hello"
    child ! Tag("This is my sample text")
  }

  def receive = {
    case x => println(x)
  }
}

object Main extends App {

  val system = ActorSystem("MySystem")

  system.actorOf(Props[ParentActor])
}

Output is:

[info] Running Main
Hello
This is my sample text@tagged

这篇关于如何应对Akka儿童演员的长时间初始化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆