能够处理一些其他的消息之前初始化一个演员 [英] Initializing an actor before being able to handle some other messages
问题描述
我有它创建另一个演员:
I have an actor which creates another one:
class MyActor1 extends Actor {
val a2 = system actorOf Props(new MyActor(123))
}
第二男主角必须初始化(引导)本身,一旦它创建,仅在它必须能够做其他的工作。
The second actor must initialize (bootstrap) itself once it created and only after that it must be able to do other job.
class MyActor2(a: Int) extends Actor {
//initialized (bootstrapped) itself, potentially a long operation
//how?
val initValue = // get from a server
//handle incoming messages
def receive = {
case "job1" => // do some job but after it's initialized (bootstrapped) itself
}
}
所以 MyActor2
的第一件事要做的就是做初始化本身的一些工作。因为它是请求到服务器可能需要一些时间。它成功完成后,才,就必须成为能够通过来处理传入的短信接收
。在此之前 - 它必须这样做。
So the very first thing MyActor2
must do is do some job of initializing itself. It might take some time because it's request to a server. Only after it finishes successfully, it must become able to handle incoming messages through receive
. Before that - it must not do that.
当然,到服务器的请求必须是异步的(preferably,使用未来
,而不是异步
,的await
或其他高层次的东西,比如 AsyncHttpClient
)。我知道如何使用的未来,这不是一个问题,虽然。
Of course, a request to a server must be asynchronous (preferably, using Future
, not async
, await
or other high level stuff like AsyncHttpClient
). I know how to use Future, it's not a problem, though.
我如何保证?
P.S。我的猜测是,它必须首先发送一个消息给它本身。
p.s. My guess is that it must send a message to itself first.
推荐答案
您可以使用成为
方法初始化后改变演员的行为:
You could use become
method to change actor's behavior after initialization:
class MyActor2(a: Int) extends Actor {
server ! GetInitializationData
def initialize(d: InitializationData) = ???
//handle incoming messages
val initialized: Receive = {
case "job1" => // do some job but after it's initialized (bootstrapped) itself
}
def receive = {
case d @ InitializationData =>
initialize(d)
context become initialized
}
}
请注意,这样的演员会在初始化之前丢弃所有消息。你会使用的 藏匿
:
Note that such actor will drop all messages before initialization. You'll have to preserve these messages manually, for instance using Stash
:
class MyActor2(a: Int) extends Actor with Stash {
...
def receive = {
case d @ InitializationData =>
initialize(d)
unstashAll()
context become initialized
case _ => stash()
}
}
如果你不想使用 VAR
初始化,您可以创建使用初始化行为 InitializationData code>是这样的:
If you don't want to use var
for initialization you could create initialized behavior using InitializationData
like this:
class MyActor2(a: Int) extends Actor {
server ! GetInitializationData
//handle incoming messages
def initialized(intValue: Int, strValue: String): Receive = {
case "job1" => // use `intValue` and `strValue` here
}
def receive = {
case InitializationData(intValue, strValue) =>
context become initialized(intValue, strValue)
}
}
这篇关于能够处理一些其他的消息之前初始化一个演员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!