scala - 在 akka/scala 中访问 actor 之外的不可变成员

标签 scala akka immutability actor future

我刚开始学习 Akka/Scala,我写了一个小型聊天服务器。

想象一下这是一个基于房间的聊天服务器,每个人都可以创建自己的房间,并且可以同时在多个房间中。每当房间的成员用完时,房间就会关闭。房间由 id: Int 标识,并且有一个不可变的 name: String .我编写了以下代码来呈现房间。

class Room(val id: Int, val name: String, var host: ActorRef) extends Actor {
  def receive = {
    case GetId() =>
      sender ! id
    case GetName() =>
      sender ! name
    case AddMember(member) => ...
    case RemoveMember(member) => ...
    case BroadcastMessage(from, message) => ...
}

现在,客户端需要所有房间的 id 和名称来决定加入哪个房间。

val rooms: List[ActorRef] // Obtained somewhere
val getIdFutures: List[Future[Int]] = rooms.map { (_ ? GetId()).mapTo[Int] }
val getNameFutures: List[Future[String]] = rooms.map { (_ ? GetName()).mapTo[String] }
val getIds: Future[List[Int]] = Future.sequence(getIdFutures)
val getNames: Future[List[String]] = Future.sequence(getNameFutures)
for (ids <- getIds; names <- getNames) yield {
  ids zip names map { pair =>
    val id = pair._1
    val name = pair._2
    println(s"$id: $name")
  }
}

嗯,好的,它有效...但是...有什么方法可以让我访问这些 不可变 成员在 Actor 内更方便?我试图为房间 Actor 制作一个包装器,如下面的代码:

case class RoomWrapper(val id: Int, val name: String, actor: ActorRef)

看起来不错,但是有个问题:现在我要通过RoomWrapper到处都是对象。房间被破坏时如何得到通知?我不能context.watch RoomWrapper !

如何解决这个问题?我有没有可能写成这样?

val rooms: List[ActorRef]
rooms map { room =>
  println(room.id)
  println(room.name)
}

最佳答案

嗯,这只是我的意见。我不认为你应该按照你的建议去做,因为这会使你的代码“多样化”(我的意思是,从 Actor 模型中分离出更具体的东西)。从技术上讲,actor 永远不应该共享任何状态,而且,他们应该只对事件(消息)使用react。在任何情况下,使用 for comprehensions 您可以将上述内容重写为:

for {
  room <- rooms
  id <- (room ? GetId).mapTo[Int]
  name <- (room ? GetName).mapTo[String]
} {
  println(id)
  println(name)
}

此外,您可以制作一条消息,将 id 和 name 作为元组返回,依此类推。可能性是无限的,但我不允许以这种方式直接访问甚至不可变状态,因为它使我对我正在编码的内容进入应用程序的特定模式的看法有点困惑。

关于scala - 在 akka/scala 中访问 actor 之外的不可变成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27588032/

相关文章:

eclipse - Scala IDE : can't read XML file into scala worksheet

scala - 如何解析 Shippable 上的 SBT 测试报告?

scala - AKKA future 和 Java 线程

for-loop - 为什么闭包中允许使用 'for .. in'?

java - 如何在java中使用路径创建 session cookie,同时仍然具有函数式编程的良好编程实践

scala - 在 Spark Streaming 应用程序中注册 UDF

json - PlayFramework 2.2 - Scala - 读取混合数组

java - Akka 基本程序无法运行

java - 分布式系统中的参与者(Akka)和代理(JADE)有什么区别?

list - scala 可变 val 列表