I was just starting to learn Akka / Scala, and I wrote a small chat server.
Imagine this is a room-based chat server, everyone can create their own room and can be in several rooms at the same time. Whenever the members run out of room, the room closes. The room is identifiable id: Intand has immutable name: String. I wrote the following code to represent the room.
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) => ...
}
Now the client needs the identifiers and names of all rooms to decide which room to join.
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")
}
}
Ok, ok, this works ... but ... are there any more ways to access those immutable members inside the Actor more conveniently? I tried to make a wrapper for the room actor, like the code below:
case class RoomWrapper(val id: Int, val name: String, actor: ActorRef)
, : RoomWrapper . , ? context.watch a RoomWrapper!
? ?
val rooms: List[ActorRef]
rooms map { room =>
println(room.id)
println(room.name)
}