【发布时间】:2018-08-12 06:27:42
【问题描述】:
我理解在基于 Actor 的系统中,比如 Akka,Actor 是独立工作的,不直接交互。相反,他们互相发送消息。演员只是发送一条消息并转到其他任务。这有助于避免阻塞。
但是如果actor在没有响应的情况下无法前进,那么它如何帮助实现异步行为呢?演员不需要等待响应吗?
【问题讨论】:
我理解在基于 Actor 的系统中,比如 Akka,Actor 是独立工作的,不直接交互。相反,他们互相发送消息。演员只是发送一条消息并转到其他任务。这有助于避免阻塞。
但是如果actor在没有响应的情况下无法前进,那么它如何帮助实现异步行为呢?演员不需要等待响应吗?
【问题讨论】:
通常,参与者不应等待响应继续执行。一个actor接收和发送消息,这是他们的目的,但是一个actor的进度是什么?参与者可以实现协议或成为协议的一部分,但阻止内部线程执行等待某个事件的到来并不是一个好主意。
class SomeActor(receiver: ActorRef) extends Actor {
case SomeMessage(msg) =>
receiver ! s"Hey ${msg}"
case SomeResponse(resp) =>
println(s"Received response ${resp}"
}
在此示例中,actor 处理 异步 SomeMessage 事件,一旦它们到达,它就会将它们发送给另一个,但它永远不会停止。任何时候都会收到对“Hey ..”消息的响应,并且演员将采取行动打印消息。
另一种可能的实现方式:
class SomeActor(receiver: ActorRef) extends Actor {
case SomeMessage(msg) =>
receiver ? s"Hey ${msg}" onComplete { case Success(resp) =>
println(s"Received response ${resp}"
}
}
我不使用它,但它也不会阻止。它为每条传入消息创建期货,并在未来的回调中处理响应。
以下内容与您的问题更相关:
class SomeActor(receiver: ActorRef) extends Actor {
case SomeMessage(msg) =>
val resp = Await.result(receiver ? s"Hey ${msg}")
println(s"Received response ${resp}"
}
}
这会阻止 future 的执行,但是这样你就将 actor 用作同步执行单元,所以在这些场景中使用 actor 没有任何意义,至少我不会这样做。
【讨论】: