2013-09-02 2 views
0

나는 잠깐 동안 Akka를 사용해 왔고, 더 간단한 프로젝트에서는 Scala 2.10 선물 만 사용했습니다. 그러나 다른 날 나는 Akka Actors와 Futures를 돌려주는 라이브러리를 섞어야만했으며, 나는 Actor 디스 패칭 시스템과 가출 미래를 어떻게 통합 할 지 확신하지 못했습니다.Akka로 외부 선물 제어하기

프로젝트에서 Akka 액터를 사용하도록 선택하면 액터 큐를 미세 조정하고 코드의 병렬 처리를 제어 할 수 있었고 결국에는 스케일 아웃 할 수있었습니다 (현재 우선 순위가 아닐지라도). 그러나, 나는 (일부러 간체)과 같은 코드가있는 경우 :

package externallib 

object DoSomething { 
    def foo(): Future[Something] = .... 
} 


package myapp 

class MyActor extends Actor { 
    def receive = { 
     case "message" => externallib.DoSomething.foo() pipeTo sender 
    } 
} 

.../ 
val actorRef = system.actorOf(Props[MyActor].withRouter(
        RoundRobinRouter(nrOfInstances = 5))) 
(0 to 20000) foreach { 

    val futureSomething = actorRef ? "message" 

} 

다음 MyActor 실제로 externallib에서 스레드를 산란하고 직접 반환을 제외하고 아무것도하지 않습니다. externallib의 미래는 궁극적으로 결과를 호출자에게 전달합니다.

그러나 이러한 방식으로 액터를 관리하는 잘 제어되는 라우터는 동일한 ExecutionContext 내에서도 액터 시스템 외부에서 생성되므로 실제로 생성되는 스레드를 제어하지 않습니다. 큰 루프의 예에서 이것은 액터에 메시지를 대기 행렬로 보내는 대신 빠르게 소비되고 20000 개의 스레드를 긴밀하게 제어되는 큐 외부에 생성한다는 것을 의미합니다.

나는 같은 것을 할 수 있다고 생각했다 :

class MyActor extends Actor { 
    def receive = { 
     case "message" => 
      val res = Await.result(externallib.DoSomething.foo(), someDuration) 
      sender ! res 
    } 
} 

이것은 externallib 완료 (또는 timesout) 될 때까지 새로운 "message"이 배우로 전송되지 않습니다 있는지 확인합니다. 그러나 실제로는 단일 계산을 기다리는 데 두 스레드 (액터의 스레드와 DoSomething의 스레드)가 필요합니다.

배우 시스템 외부에서 생성되는 이러한 미래를 제어하는 ​​더 좋은 방법이 있습니까? 배우와 미래의 사용이 교착 상태 것이라는 ExecutionContext에 단지 하나의 스레드가있는 경우 MyActor 위험한 보이는

+0

DoSomething은 어떤 ExecutionContext를 사용합니까? –

+0

lib가 실행 컨텍스트를 지정할 수있는 방법으로 구현되고 액터가 디스패처 실행 컨텍스트를 제공한다고 가정합시다. 더 좋은 방법이 없다면 – Mortimer

+1

ExecutionContext를 만들 수 있습니다. ExecutionContext는 runnable을 액터로 간단하게 보내고 (reportFailure는 액터의 dispatcher의 reportFailure에 위임합니다), 액터는 Runnables를 받아 실행할 수 있습니다. –

답변

0

는 배우의 내부에 차단하는 것은, 참으로, 정말 좋은 생각이 아니다. 글을 쓰는 더 좋은 방법은 미래에 onComplete을 넣고, 연기자에게 새로운 선물을 보내지 않는 행동에 become을 할 것입니다. (들어오는 모든 메시지를 stash 보낼 가능성이 있습니다). onComplete은 보낸 사람에게 메시지를 보내고 배우에게 메시지를 보내어 원래의 동작 인 become을 알릴 수 있습니다.

+0

흥미 롭습니다. 액터 내에서 메시지를 제거하면 부모 구성에서 지정된 라우터를 통해 액터로 돌아갑니다. – Mortimer

+0

대답이 '아니오'라고 생각합니다. akka 문서는 "숨겨진 모든 메시지는 'unstashed'될 수 있으므로 라우터의 메일 박스에 붙여 넣을 수 있습니다. 라우터를 통해 메시지를 다시 전송하여 구현할 수 있다고 생각하지 않습니다. – wingedsubmariner