我的实际用例是MyActor收到一条消息以开始它的工作。该作业需要下载几个网页,因此要求MyActor下载。每次文章完成下载时,MyActor都会响应。
我的代码有更好的设计模式吗?似乎允许多个actor更新count变量是不好的,因为我只关心每个actor的特定计数。
主要演员:
val count = 0
def receive = {
case CountUpdate => count += 1
case Job => {
List(1, 2, 3).map{case num =>
(new myActor ? ToDownload)
val tries = 0
while (tries < 10){
print("Count is: " + count)
tries += 1
// sleep 10 seconds
}
count = 0
}
}
}
MyActor:
def receive = {
case ToDownload => sender ! CountUpdate
}
编辑:
如果我按照建议使用期货,这不会导致竞争条件吗?
var downloads: List[Int] = List()
urls.map{ case url => Future{ download(url) }.onComplete{
case Success(value) => downloads = downloads :+ value
case Failure(value) => println("Failure")
}
}
答案 0 :(得分:1)
您还可以创建Future
来下载资源。一旦未来完成,您可以向主角发送更新消息,该消息可以对其做出反应。 Future
由executionContext
执行。
class MainActor extends Actor {
var count = 0
override def receive: Receive = {
case CountUpdate =>
count += 1
println("New count " + count)
case Job =>
val batchIDs = List(1, 2, 3)
implicit val executionContext = ExecutionContext.fromExecutor(new ForkJoinPool())
batchIDs.map {
batchID =>
Future {
// do some work
}.onSuccess{
case _ => self ! CountUpdate
}
}
}
}
答案 1 :(得分:1)
我会向资源加载演员发送scala.concurrent.Promise
,然后您可以在其上拨打.future
来获取scala.concurrent.Future
。
资源加载器在.complete()
上调用Promise
,这反过来将导致调用Future
上的完整处理程序。