방금 Akka/Scala를 배우기 시작했고 작은 대화방을 작성했습니다.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")
}
}
음, 좋아, 그것은 ... 작동 ...하지만 더 편리하게 배우 내부에 그 불변 멤버에 액세스 할 나를 위해 어떤 방법이 있습니까? 나는 아래의 코드처럼, 객실 배우에 대한 래퍼를 만들려고 :
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'에서'case 클래스 ImmutableRoomData (id : Int, name : String)'을 호출 한 다음 한 번만 검색하면'zip'을하지 않아도됩니다. 또한 map-sequence 콤보는 scalaz'traverse'와 같이 더 간결하게 작성할 수 있습니다. – lmm
@Imm 나는 ImmutableRoomData 아이디어가 기본적으로 언급 한 튜플 하나와 같다고 생각하지만, 트래버스 함수는 매우 좋은 포인트입니다! 나는 그것을 사용해야한다! –