2014-12-21 5 views
4

방금 ​​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.watchRoomWrapper! 할 수 없다!

해결 방법? 이렇게 쓸 수있는 가능성이 있습니까?

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

그 반대의 경우는 어떨까요? 'Actor'에서'case 클래스 ImmutableRoomData (id : Int, name : String)'을 호출 한 다음 한 번만 검색하면'zip'을하지 않아도됩니다. 또한 map-sequence 콤보는 scalaz'traverse'와 같이 더 간결하게 작성할 수 있습니다. – lmm

+0

@Imm 나는 ImmutableRoomData 아이디어가 기본적으로 언급 한 튜플 하나와 같다고 생각하지만, 트래버스 함수는 매우 좋은 포인트입니다! 나는 그것을 사용해야한다! –

답변

2

음, 이것은 제 의견입니다. 나는 당신이 제안한대로해야한다고 생각하지 않는다. 그것은 코드를 "다변화"할 것이기 때문이다. (나는 배우 모델에서 좀 더 구체적인 것들로) 말이다. 기술적으로 말하자면, 배우들은 결코 어떤 주를 공유해서는 안되며, 또한 이벤트 (메시지)에만 반응해야합니다.

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

는 또한, 당신이 그렇게에 튜플 ID와 이름을 모두 반환하는 메시지를 확인하고 수 : 어떠한 경우에, 함축에 사용 당신은 위의 내용을 다시 작성할 수 있습니다. 가능성은 무한하지만, 내가 그 응용 프로그램의 특정 패턴에 들어가는 것을 코딩하는 것에 대한 나의 비전을 조금 어수선하기 때문에 나는 그런 식으로 불변 상태에 직접 접근하는 것을 허용하지 않을 것이다.