Akka:演员沟通的未来?

时间:2015-11-09 17:22:46

标签: scala concurrency akka actor future

我有一个系统可以产生一个会产生许多未来的演员。其中一些未来会遇到需要产生更多期货的情景(但请告诉演员)。在完成未来的操作后,如何将未来的消息发送给演员?

我查看了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'
}

1 个答案:

答案 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