首页 文章

Akka:演员沟通的未来?

提问于
浏览
0

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

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

actor的receive方法执行以下操作:

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

  • 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的使用,以便爬虫不需要知道消息传递的细节 . 这是更多的"functional"方法,如果您切换到Futures甚至akka.stream.scaladsl.Source for reactive streams(参见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 函数提供默认"do nothing"行为:

    class crawler(string : String, sendChar : (Char) => Unit = {_=>}) {
      ...
    }
    
    val crawler = crawler("foo") //still get regular Future behavior for status
    

相关问题