2014-10-17 4 views
1

Akka를 사용하여 계승을 계산하는 다음 스칼라 코드를 고려해보십시오. 출력을 얻는 방법을 모르겠습니다.Akka : 결과를 얻는 방법?

import scala.annotation.tailrec 
import akka.actor.{Actor, ActorLogging, ActorSystem, Props} 
import scala.concurrent.Await 
import akka.pattern.ask 
import akka.util.Timeout 
import scala.concurrent.duration._ 

case class GetResult() 

class FactorialCalculator extends Actor { 
    def receive = { 
    case num: Int => sender ! (num, factor(num)) 
    } 

    private def factor(num: Int) = factorTail(num, 1) 

    @tailrec private def factorTail(num: Int, acc: BigInt): BigInt = { 
    (num, acc) match { 
     case (0, a) => a 
     case (n, a) => factorTail(n - 1, n * a) 
    } 
    } 
} 

class FactorialCollector(factorials: List[Int]) extends Actor with ActorLogging { 
    var list: List[BigInt] = Nil 
    var size = factorials.size 

    for (num <- factorials) { 
    context.actorOf(Props(new FactorialCalculator)) ! num 
    } 

    def receive = { 
    case (num: Int, fac: BigInt) => { 
     log.info(s"factorial for $num is $fac") 

     list = fac :: list 
     size -= 1 

     if (size == 0) { 
     log.info(list.toString) 
     context.system.shutdown() 
     } 
    } 

    case GetResult => sender ! list 
    } 
} 

class Factorial(factorials: List[Int]) { 

    val system = ActorSystem("factorial") 

    val collector = system.actorOf(Props(new FactorialCollector(factorials)), "collector") 

    implicit val timeout = Timeout(10 seconds) 
    val future = collector ? GetResult 
    val result = Await.result(future, timeout.duration) 

    system.awaitTermination() 
} 


var x = new Factorial(List(50, 18, 32, 28, 22, 42, 55, 48)) 

결과는 클래스 FactorialCollector에서 계산 된 변수 list에 저장하지만, 빈 listx.result 반환된다.

답변

1

먼저 양식 context.actorOf(Props(new FactorialCalculator))를 사용하지만 안 님의 정수로 목록을 제공하는 대신

def receive = { 
    .... 
    case GiveMeResult => sender ! list 
    .... 
} 

또는 : context.actorOf(Props[FactorialCalculator])source

두 번째로는, 예를 들어, anwser에 대한 FactorialCollector에 messege를 보낼 수 있습니다 생성자에서 계산하면 요청 방법으로 Collector에 보낼 수 있습니다. 그러면 계산 결과와 함께 미래가 있습니다.

+0

마리우스에 감사드립니다. 하지만 저는 스칼라에서 초보자이며 몇 시간을 보내서 몇 가지 문서를 읽은 후에 결과를 얻을 수 없었습니다. 당신의 대답은 내가 지금까지 읽은 것보다 덜 정확하고 슬프게도 나를 도와주지 않습니다. –

+0

나는 약간의 진전을 이뤘고 이에 따라 나의 질문을 업데이트했다. 그러나 나는 아직 결과를 얻지 못했다. –

+0

마지막 factorial이 actor :'context.system.shutdown()'에 의해 계산 될 때 시스템을 종료합니다. 이 행을 제거하십시오. 또한 당신은 시스템이 필요 없습니다. 와일드 결과를 기다리고 있습니다. 대신 이것은 계승 클래스의 마지막 줄에'system.shutdown()'을 넣는다. –

0

보낼 getResult를 메시지를 FactorialCollector를 수집하기 전에 FactorialCalculators

의 모든 결과는 대신

for (num <- factorials) { 
    context.actorOf(Props(new FactorialCalculator)) ! num 
    } 

당신이

val res = Await.result(Future.traverse(factorials)(context.actorOf(Props(new FactorialCalculator)) ? _), timeout) 

필요하지만 기다리고 있습니다 못생긴받을 - akka 이것을 사용하지 마십시오 :).

stash/unstashAll 및 context.become (..)

+0

이 오류가 발생합니다. 'error : 암시 적 ExecutionContext를 찾을 수 없거나 scala.concurrent.ExecutionContext.Implicits를 가져옵니다. 전역 또는 사용자 정의를 사용하십시오 ' –

+0

좋아요. 선 앞에'import scala.concurrent.ExecutionContext.Implicits.global'을 추가하여 실행하지만 프로그램이 차단됩니다 (멈추지 않고 아무 것도 인쇄하지 않음). 완전한 코드가 없으면 절대로 이해할 수 없을 것입니다. –