2013-12-11 2 views
1

나는 scala를 사용하여 akka 배우 시스템을 실행 중입니다. 이제 여러 장치를 병렬로 구성해야 모든 구성 작업을 관리하는 Manager 액터가 있습니다. 실제로 구성하려면 구성당 Worker 액터를 생성하여 동시에 또는 병렬로 실행합니다. 이제 Worker 배우는 구성 중에 관리자로부터 메시지를받을 필요가 없으며 자신의 일을 수행하기 만하면 Manager으로 끝났음을보고합니다.배우 좋은 연습?

이제 문제는 내가 지침과 Worker의 생성자에서 ManagerActorRef을 전달하거나 내가 만든 다음 Do(action: => Unit)처럼 메시지를 전송 할 수 있으며 다음 완료되면 sender에 응답 할 것이다합니까입니까? 대회를하는 방법이나 좋은 연습으로 간주되는 대회가 있습니까?

편집는 : 블라디미르 Matveev는 Manager 나에게 참조를 연상으로 이미 context.parent의 계층 구조를 통해 알려진대로 문제가되지 않습니다. 그것은 Worker에 작업을 전달하는 방법에 대한 질문 만 남깁니다.

+1

'Manager'가 작업자를 직접 스폰하면, 관리자에게'Manager' 참조를 전달할 필요가 없습니다. worker는'context.parent'를 사용하여'Manager''' ActorRef'에 접근 할 수 있습니다. –

+0

@VladimirMatveev 오, 그래 그게 사실이야. 그러나 그들이해야 할 일은 무엇입니까? 'context.scheduler.schedule ...'을 사용하여 미래에 생성 할 경우'context.parent'는 여전히'Manager'입니다. 나는 그것을 폐쇄가되어야한다고 생각하지만 그것에 대해서는 확실하지 않습니다. – mgttlinger

+1

액터 내에서'context'를 사용하여 자식 액터를 스폰하면, 액터 내부에서'context'를 사용하는 위치에 상관없이이 액터를 부모로 갖게됩니다. 당신이 말했듯이,'context' 변수는 막혀 있지만, 여전히'context' 변수이기 때문에 꽤 논리적입니다. –

답변

2

맞습니다. 작업은 메시지를 통해 작업자에게 전달되어야합니다. 이것이 배우와 의사 소통하는 가장 안전한 방법이기 때문입니다. 또한 배우 앞에서 디스패처를 사용하여 할당 된 작업을 여러 작업자로 나눌 수 있습니다.

import akka.actor.Actor 
import akka.actor.Props 

case class Start() 
case class Finished() 
case class Do(action:() => Unit) 

class Manager extends Actor { 

    override def preStart() = 
    self ! Start() 

    def receive = { 
    case Start() => 
     val workers = context.actorOf(
     Props[Worker].withRouter(RoundRobinRouter(nrOfInstances = 5))) 
     context.system.scheduler.schedule(5 seconds, 5 seconds, workers, Do(() => 1 * 1)) 

    case Finished() => 
     println("A worker finished work.") 
    } 
} 

class Worker extends Actor { 
    def receive = { 
    case Do(f) => 
     f() 
     sender ! Finished() 
    } 
} 

관리자가 시작됩니다 후에는 5 명 근로자를 생성하고 5 초마다 작동 뭔가를 보내드립니다 :

하는 것을 명확하게하기 위해, 여기에 간단한 예입니다. 근로자는 작업을 끝내고 작업을 마칠 때 다시보고합니다. 완성 된 작업을보고하기 위해 sender (항상 작업 발행자에게보고) 또는 context.parent (항상 관리자에게보고)을 사용할 수 있습니다.

관련 문제