我开始学习Akka,在许多官方例子中,我看到request-response使用tell模式实现.也就是说,在工人完成工作后,他将结果作为新消息发送给发件人.例如,在这个 Pi近似官方教程中展示了如何设计应用程序,其中Master向工作人员发送一些工作,然后等待结果作为另一个消息.
主码:
def receive = {
case Calculate ?
for (i ? 0 until nrOfMessages) workerRouter ! Work(i * nrOfElements, nrOfElements)
case Result(value) ?
pi += value
nrOfResults += 1
if (nrOfResults == nrOfMessages) {
// Send the result to the listener
listener ! PiApproximation(pi, duration = (System.currentTimeMillis - start).millis)
// Stops this actor and all its supervised children
context.stop(self)
}
}
Run Code Online (Sandbox Code Playgroud)
工人代码:
def receive = {
case Work(start, nrOfElements) ?
sender ! Result(calculatePiFor(start, nrOfElements)) // perform the work
}
Run Code Online (Sandbox Code Playgroud)
但我想知道为什么这个例子没有使用ask模式?在这里使用ask模式有什么问题?
如果可以在这里使用ask模式,那么我还有另一个问题:如何在完成工作后停止所有工人演员?
PoisonPill向自己发送信息吗?Broadcast(PoisonPill)吗?ask在将actor与FutureAPI 集成时非常有用,但它们确实会引入一些开销.此外,Future完成不是通过actor的邮箱来进行的,而是安排在与邮箱使用的线程分开的线程上,这意味着在actor内部接收未来的完成会引入进行多线程协调的需要.
同时,如果您使用tell发送给工作人员并将其tell作为sender响应,则通信将始终通过邮箱通道正常流动.
另外,如果一个演员都是通过来自receive而不是一些来自via receive和其他作为ask消息的完成,则更容易辨别演员处理的输入.
为了解决您的PoisonPill问题,答案可能取决于.您可以选择每个消息的工作方法,在这种情况下,工作人员应该自杀.相反,如果您使用工作池,则可以让主管负责上下缩放该池,让它发送PoisonPill或让工作人员闲置时间,再次自杀.
| 归档时间: |
|
| 查看次数: |
564 次 |
| 最近记录: |