2014-04-17 2 views
1
import akka.actor._ 
case object ChildMessage 

implicit val as = ActorSystem() 

class Child extends Actor { 
    def receive = { 
    case ChildMessage => println("I'm a child") 
    } 
} 

class ParentWithExplicitChildren extends Actor { 
    val children = Array.fill(5)(context.actorOf(Props[Child])) 
    def receive = { 
    case ChildMessage => children.foreach(_ ! ChildMessage) 
    case _ => println("I'm a parent") 
    } 
} 

class ParentWithActorRefs extends Actor { 
    val shamChildren = Array.fill(5)(as.actorOf(Props[Child])) 
    def receive = { 
    case ChildMessage => shamChildren.foreach(_ ! ChildMessage) 
    case _ => println("I'm a parent") 
    } 
} 

val parent = as.actorOf(Props[ParentWithExplicitChildren]) 
parent ! ChildMessage 
// Will shut down children 
parent ! PoisonPill 


val shamParent = as.actorOf(Props[ParentWithActorRefs]) 
shamParent ! ChildMessage 
// WONT shut down children 
shamParent ! PoisonPill 

위 예제를 사용하면 명시 적 부모 자식 관계가없는 두 가지 결과 만 생각할 수 있습니다.akka에서 부모 자식 관계의 결과

  1. 포이즌 필은 명시 적으로
  2. ParentWithActorRefs의 context.children이

들이 다른 결과 있습니까 비어 있습니다 ParentWithActorRefs에 포함 된 배우 심판을 죽일 것인가? 자식이 아닌 메시지 중계는 하위 메시지 중계와는 다른 메시지 순서 지정 의미를 가질 수 있습니까? actorSelection을 사용하여 ParentWithExplictChildren의 하위 액터 ref에 액세스 할 수 있습니까?

+1

'ParentWithExplicitChildren'에서 노트처럼, 아이들은 항상'context.children'을 통해 접근 할 수 있기 때문에'val children'을 필요로하지 않습니다. 이러한 참조를 유지하기 위해 명시 적으로 'val'이 필요하지 않습니다. – cmbaxter

+0

또한 최상위 "자식"을 만들기 위해 "as"를 닫을 필요가 없습니다. 단지 "context.system"을 사용하십시오. –

답변

2

첫 번째 두 가지 결과가 정확합니다. 그러나 ParentWithExplicitChildren 자체가 실패하면 그 아이들을위한 명시적인 감독자이기 때문에 아이들이 모두 멈추고 다시 시작할 것입니다. ParentWithActorRefs의 경우이 감독자가 실패하면 감독자가 아니기 때문에 shamChildren이 중지되지 않습니다. 루트 수호자가 있습니다.

또한 예, 액터 선택을 통해 ParentWithExplicitChildren 개의 참조 파일에 액세스 할 수 있습니다. 그들은 접근 가능한 경로를 가진 적절한 배우이며 따라서 부모/감독하는 배우의 외부에서 찾아보고 전달할 수 있습니다.

관련 문제