【问题标题】:Access an immutable member outside of an actor in akka/scala在 akka/scala 中访问演员之外的不可变成员
【发布时间】:2015-02-19 16:29:31
【问题描述】:

刚开始学习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 内的那些 不可变 成员?我尝试为房间演员制作一个包装器,如下面的代码:

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

看起来不错,但有一个问题:现在我必须到处传递RoomWrapper 对象。房间被破坏时如何得到通知?我不能context.watchRoomWrapper

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

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

【问题讨论】:

  • 反过来呢? case class ImmutableRoomData(id: Int, name: String)Actor 中,然后你只需要检索一次就可以避免zip。此外,map-sequence 组合可以更简洁地写为 scalaz traverse
  • @Imm 我认为 ImmutableRoomData 的想法和 kaktusito 提到的元组基本相同,但是traverse function 是一个非常好的点!我应该使用它!

标签: scala akka immutability actor future


【解决方案1】:

嗯,这只是我的意见。我认为你不应该按照你的建议去做,因为这会使你的代码“多样化”(我的意思是,从演员模型中变成更具体的东西)。从技术上讲,参与者不应该共享任何状态,而且,他们应该只对事件(消息)做出反应。在任何情况下,使用 for 推导式都可以将上面的内容重写为:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-23
    • 2014-06-13
    • 2021-05-13
    • 2013-07-20
    • 1970-01-01
    • 1970-01-01
    • 2011-07-08
    • 1970-01-01
    相关资源
    最近更新 更多