我有一个系统可以产生一个会产生许多未来的演员。其中一些未来会遇到需要产生更多期货的情景(但请告诉演员)。在完成未来的操作后,如何将未来的消息发送给演员?
我查看了pipeTo
文档,但在将来的课程中我无法引用系统中的actor。
这是我的Future类的样子:
class crawler(string: String) {
val status: Future[Boolean] = Future[Boolean] {
//Do something with content
println("I am a future working on cert crawling. My cert contents are: " + cert.content)
true
}
status onComplete {
case Success(true) =>
for(chars <- string.toCharArray) {
//send actor a message for each character of the string.
}
case Failure(t) => println("An error has occured: " + t.getMessage)
}
}
演员的接收方法执行以下操作:
def receive = {
case c:Char => if(!certCache.containsKey(c)){
println("actor >>>> Need to begin crawl on " + c + ".")
sender() ! new crawler("give sender the future")
case _ => println("That's not the right input!")
}
而且,我的演员产生了如下:
object Main extends App {
val system = ActorSystem("MySystem")
val actor = system.actorOf(Props[actorClass], name = "actor")
actor ! 'a'
}
答案 0 :(得分:2)
您可以依赖将ActorRef注入您的Future(不推荐,请参阅Abstracted):
import akka.actor.ActorRef
//dependency injection of the ActorRef with a default value of noSender
class crawler(string : String, actorRef : ActorRef = ActorRef.noSender) {
...
status OnComplete {
//send each Char in string to the actorRef
case Success(true) => string.foreach(actorRef ! _)
...
}
然后在您的Actor中,您可以使用self
将ActorRef传递给爬虫:
def receive = {
case c : Char => if(!certCache.containsKey(c)) {
sender() ! new crawler("give sender the future", self)
}
}
此外,您可以完全抽象出ActorRef的使用,以便爬虫不需要知道消息传递的细节。这是一种更具“功能性”的方法,如果您切换到期货,甚至可以转换为reactive streams 的akka.stream.scaladsl.Source,那么它具有可扩展性的好处(参见example):
//no akka imports or dependencies
class crawler(string : String, sendChar : (Char) => Unit) {
...
case Success(true) => string foreach sendChar
}
在你的Actor中你可以将一个匿名函数传递给crawler,它通过self向Actor发送一个Char:
def receive = {
case c : Char => if(!certCache.containsKey(c)) {
sender ! new crawler("give sender the future", self ! _)
}
}
您甚至可以为sendChar
功能提供强大的功能并提供默认的“不执行任何操作”:
class crawler(string : String, sendChar : (Char) => Unit = {_=>}) {
...
}
val crawler = crawler("foo") //still get regular Future behavior for status