Scala Akka:演员交流的未来?
我有一个系统,产生一个单一的演员谁将产生许多未来。其中一些未来会遇到需要产生更多未来的场景(但要告诉参与者)。我如何在未来操作完成时向参与者发送来自未来的消息 我已经看过了Scala Akka:演员交流的未来?,scala,concurrency,akka,actor,future,Scala,Concurrency,Akka,Actor,Future,我有一个系统,产生一个单一的演员谁将产生许多未来。其中一些未来会遇到需要产生更多未来的场景(但要告诉参与者)。我如何在未来操作完成时向参与者发送来自未来的消息 我已经看过了pipeTo文档,但在未来的课程中,我很难引用系统中的参与者 以下是我未来的课程: class crawler(string: String) { val status: Future[Boolean] = Future[Boolean] { //Do something with content p
pipeTo
文档,但在未来的课程中,我很难引用系统中的参与者
以下是我未来的课程:
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)
}
}
我的演员是这样产生的:
object Main extends App {
val system = ActorSystem("MySystem")
val actor = system.actorOf(Props[actorClass], name = "actor")
actor ! 'a'
}
直接地
您可以将依赖项注入ActorRef到未来(不推荐,请参阅摘要):
然后在您的Actor中,您可以使用self
将ActorRef传递到爬虫:
def receive = {
case c : Char => if(!certCache.containsKey(c)) {
sender() ! new crawler("give sender the future", self)
}
}
抽象的
此外,您可以完全抽象出ActorRef的使用,这样爬虫程序就不需要知道消息传递的细节。这是一种更具“功能性”的方法,如果您切换到Futures甚至akka.stream.scaladsl.Source,它的优点是可扩展(请参阅):
在您的Actor中,您可以向crawler传递一个匿名函数,该函数通过self向Actor发送一个字符:
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
如果你不提供一个简单的例子来说明你正在尝试做什么,那么回答这样的问题就很难了。你不能让你基于未来的工作流自包含,并且只在最后一次嵌套的未来完成时通知参与者(使用pipeTo)?如果您有一个需要传回多个结果的计算,也许akka stream比futures更匹配?我更新了我的问题,加入了@AldostracQuadani的代码片段。您提供的两个类似乎不相关,参与者如何使用爬虫?另外,@RüdigerKlaehn还提出了一个很好的建议:如果演员收到了很多字符,为什么不能接收字符串?我再次更新了我的问题,以显示演员的接收方法。在这个特定示例的上下文中,使用流可能很有用,但在我的最终结果中,我不想做@RüdigerKlaehn所说的事情。
//no akka imports or dependencies
class crawler(string : String, sendChar : (Char) => Unit) {
...
case Success(true) => string foreach sendChar
}
def receive = {
case c : Char => if(!certCache.containsKey(c)) {
sender ! new crawler("give sender the future", self ! _)
}
}
class crawler(string : String, sendChar : (Char) => Unit = {_=>}) {
...
}
val crawler = crawler("foo") //still get regular Future behavior for status