我对akka很新,不确定是否接近这个问题。
我有一个Monitor
演员,以DiskMonitor
和MemoryMonitor
DiskMonitor
检查diskUsage并报告DiskReport
消息
MemoryMonitor
检查diskUsage并报告MemoryReport
消息我想将DiskReport
和MemoryReport
合并到Report
对象中,并通过API发送到远程计算机。
问题
由于DiskMonitor
和MemoryMonitor
都是演员,因此他们在完成工作后会将响应发送回来电
监控
diskMonitor ! DiskMonitorRequest
memoryMonitor ! MemoryMonitorRequest
Monitor
如何知道它具有所需的所有结果,以便它可以创建Report
对象并通过API发送它?
演员是解决这个问题的好方法吗?
我也读到了关于未来但我不太了解它们并且不确定它们是否会对这个问题背景有所帮助
答案 0 :(得分:1)
这是做这些事情的简单方法。其他选项可以使用context.become
或特征FSM
。
class Monitor extends Actor {
// Somewhere do this:
diskMonitor ! DiskMonitorRequest
memoryMonitor ! MemoryMonitorRequest
var diskMonitorResult = Option.empty[DiskMonitor]
var memoryMonitorResult = Option.empty[MemoryMonitor]
def recieve = {
case d: DiskMonitor =>
diskMonitorResult = Some(d)
checkIfCompleted()
case m: MemoryMonitor =>
memoryMonitorResult = Some(m)
checkIfCompleted()
}
def checkIfCompleted = {
(diskMonitorResult, memoryMonitorResult) match {
case (Some(diskMonitor), Some(memoryMonitor)) =>
// send to external API
externalApi ! Report(diskMonitor, memoryMonitor)
// Possibly stop this actor
case _ => // do nothing
}
}
}
答案 1 :(得分:0)
您可以使用询问模式并结合期货..
import akka.actor._
import akka.pattern.ask
import akka.util.Timeout
import scala.concurrent.duration._
sealed trait Message
case object Create extends Message
case object MakeDiskReport extends Message
case object MakeMemoryReport extends Message
case class DiskReport(report: String) extends Message
case class MemoryReport(report: String) extends Message
case class Report(memReport: String, diskReport: String) extends Message
class Monitor extends Actor with ActorLogging {
implicit val timeout = Timeout(5 seconds)
implicit val ec = context.dispatcher
val diskM = context.system.actorOf(Props[DiskMonitor])
val memoryM = context.system.actorOf(Props[MemoryMonitor])
val remoteM = context.system.actorOf(Props[RemoteMachine])
override def preStart = {
// can also be send at start of actor creation or scheduled
log.info("Monitor Created..")
self ! Create
}
override def receive = {
case Create => {
ask(diskM, MakeDiskReport).mapTo[DiskReport]
.flatMap { diskR =>
ask(memoryM, MakeMemoryReport)
.mapTo[MemoryReport].map { memR => remoteM ! Report(memR.report, diskR.report) }
}
}
}
}
class DiskMonitor extends Actor with ActorLogging {
override def receive = {
case MakeDiskReport => {
log.info("Creating DiskReport..")
val client = sender
client ! DiskReport("DiskReport")
}
}
}
class MemoryMonitor extends Actor with ActorLogging {
override def receive = {
case MakeMemoryReport => {
log.info("Creating MemoryReport..")
val client = sender
client ! MemoryReport("MemoryReport")
}
}
}
class RemoteMachine extends Actor with ActorLogging {
override def receive = {
case Report(memr, diskr) => {
log.info(s"Final Report.. $memr, $diskr")
}
}
}
object Main extends App {
val sys = ActorSystem()
sys.actorOf(Props[Monitor])
}