나는 잠깐 동안 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 위험한 보이는
DoSomething은 어떤 ExecutionContext를 사용합니까? –
lib가 실행 컨텍스트를 지정할 수있는 방법으로 구현되고 액터가 디스패처 실행 컨텍스트를 제공한다고 가정합시다. 더 좋은 방법이 없다면 – Mortimer
ExecutionContext를 만들 수 있습니다. ExecutionContext는 runnable을 액터로 간단하게 보내고 (reportFailure는 액터의 dispatcher의 reportFailure에 위임합니다), 액터는 Runnables를 받아 실행할 수 있습니다. –