Scala 在一个参与者中从多个参与者收集数据的最佳方式是什么?

Scala 在一个参与者中从多个参与者收集数据的最佳方式是什么?,scala,concurrency,actor,Scala,Concurrency,Actor,从一个参与者中的多个参与者收集数据并在处理后将其发送给另一个参与者的最佳方式是什么? 我可能有自己的体会: import scala.actors._ abstract class Message case class DataMsg(id: String, value: String) extends Message case class Done() extends Message class DataSender(id: String, next: Actor) extends Act

从一个参与者中的多个参与者收集数据并在处理后将其发送给另一个参与者的最佳方式是什么? 我可能有自己的体会:

import scala.actors._

abstract class Message
case class DataMsg(id: String, value: String) extends Message
case class Done() extends Message

class DataSender(id: String, next: Actor) extends Actor {

    def act() {
        loop {
            react {
                case DataMsg(_, msg) => next ! DataMsg(id, msg)
                case Done() => {
                    println(id+" -> done")
                    exit()
                }
            }
        }
    }
}

class Concat(next: Actor, ids: Seq[String]) extends Actor {
    private val data = scala.collection.mutable.LinkedHashMap.empty[String, String]

    def act() {
        loop {
            react {
                case DataMsg(id, msg) => {
                    if (ids contains id) {
                        data(id) = msg
                        if (ids.size == data.keys.size) {
                            next ! DataMsg("", data.values.mkString)
                            data.clear
                        }
                    }
                }
                case Done() => {
                    println("Concat -> done")
                    exit()
                }
            }
        }
    }
}

class PrintData extends Actor {
    def act() {
        loop {
            react {
                case DataMsg(_, msg) => {
                    println("Data: " + msg)
                }
                case Done() => {
                    println("PrintData -> done")
                    exit()
                }
            }
        }
    }
}

val printData = new PrintData
val concat = new Concat(printData, Seq("f1", "f2", "f3"))
val f1 = new DataSender("f1", concat)
val f2 = new DataSender("f2", concat)
val f3 = new DataSender("f3", concat)

printData.start
concat.start
f1.start
f2.start
f3.start

f1 ! DataMsg("", "Hello")
f2 ! DataMsg("", " ")
f3 ! DataMsg("", "Wordl!")
Thread.sleep(1000)
f1 ! Done()
f2 ! Done()
f3 ! Done()
concat ! Done()
printData ! Done()

也许,有更好的解决办法。我考虑过未来,但我不确定是否有必要使用它们。如果Concat actor无法获取值,我该怎么办?

您可以用case类DataMessage(id:String,value:String)替换case类DataMessag(id:String,value:Option[String])。这对我有什么帮助?如果DataSender无法发送消息,它将在该消息之后不发送任何消息。Concat将引发异常?如果在选项集合上使用flatMap(a=>a),您将只获得一些选项的值。没有的将被丢弃。我没有问题丢弃或处理一些东西。Concat参与者必须获取所有消息,并且只有在获取这些消息之后才能将结果发送给下一个参与者。如果Concat actor无法获得消息,则表明系统崩溃,那么最好的通知方式是什么?第二个问题,等待所有消息的最佳方式是什么?现在我明白了。通知崩溃或成功的一种方法是使用()或()。