2014-01-28 1 views
0

나는 돌연변이 방법 인 생성자 arg로 액터를 배치 할 라우터를 만들려고합니다.액터 생성자 (Arguments with Router)

object LocalRouterArgEvalFrequency { 
    def main(args: Array[String]) { 
    val system = ActorSystem("TestSystem") 
    var number = 0 

    def getANumber: Int = { 
     number += 1 
     number 
    } 

    val router = system.actorOf(Props(classOf[Foo], getANumber) 
           .withRouter(RoundRobinRouter(5)), "RRRouter") 
    (1 to 10).foreach(_ => router ! "What's Your Number?") 
    } 
} 

class Foo(number: Int) extends Actor { 
    println("I got instantiated") 
    def receive: Actor.Receive = { 
    case msg: String => println(s"My Number is $number") 
    } 
} 
내가 출력으로이 라인을 따라 뭔가를 보여야하는데

는 (나는이 RoundRobin 마지막으로 내가 보장 그래서 확인 최선의 노력이라고 생각) :

I got instantiated 
I got instantiated 
I got instantiated 
I got instantiated 
I got instantiated 
My Number is 1 
My Number is 1 
My Number is 1 
My Number is 1 
My Number is 1 
My Number is 1 
My Number is 1 
My Number is 1 
My Number is 1 
My Number is 1 
:

I got instantiated 
I got instantiated 
I got instantiated 
I got instantiated 
I got instantiated 
My Number is 1 
My Number is 2 
My Number is 3 
My Number is 4 
My Number is 5 
My Number is 1 
My Number is 2 
My Number is 3 
My Number is 4 
My Number is 5 

대신 나는 다음과 같은 볼을

나는 이런 돌연변이를 주입하는 것이 좋은 아이디어 패턴이 아니라는 것을 잘 알고 있지만 테스트 코드에서이 유형의 상호 작용과 매우 흡사 한 유스 케이스가있다.

라우터를 배포 할 때마다 평가할 수있는 방법이 있습니까? 아니면 내가 볼 수없는 다른 방법이 있습니다 ... 미리 감사드립니다!

답변

3

한 가지 명심해야 할 것은 생성자 arg 값이 현재 접근 방식으로 한 번 캡처된다는 것입니다. 다른 말로하면, getANumber은 실제로 한 번만 호출되며 그 결과 (이 경우 1)는 라우터가 만든 모든 액터에 대한 생성자 arg로 사용됩니다. 각 다음 고유 번호를 원한다면 당신이 대신 같은 것을 시도 할 수 있습니다 :

object LocalRouterArgEvalFrequency { 
    def main(args: Array[String]) { 
    val system = ActorSystem("TestSystem") 
    var number = 0 

    def getANumber: Int = { 
     number += 1 
     number 
    } 
    val routees = List.fill(5)(getANumber).map(i => system.actorOf(Props(classOf[Foo], i))) 
    val router = system.actorOf(Props.empty.withRouter(RoundRobinRouter(routees = routees)), "RRRouter") 
    (1 to 10).foreach(_ => router ! "What's Your Number?") 
    } 
} 

class Foo(number: Int) extends Actor { 
    println("I got instantiated: " + number) 
    def receive: Actor.Receive = { 
    case msg: String => println(s"My Number is $number") 
    } 
} 

편집

또한과 같이 Props.apply의 다른 변형을 사용하여 라우터를 만들 수 있습니다

val router = system.actorOf(Props(new Foo(getANumber)).withRouter(RoundRobinRouter(5)), "RRRouter") 

그 접근 방식은 당신이 찾고있는 것 이상의 것일 수 있습니다.

+0

그건 내가 생각한거야. 확인해 주셔서 감사합니다. 라우터 또는 소품을 매번 다시 평가하도록하는 방법이 있습니까? – Ceryni

+0

@Ceryni, 예, 업데이트 참조 – cmbaxter

+0

우수! 첫 번째 요점을 설명하고 내가 원하는 구체적인 대답으로 좁혀 주셔서 감사합니다. 감사! – Ceryni