2009-06-05 4 views
1

핸들러에서 새 액터를 만들 때이 스칼라 액터가 차단됩니까?

다음 코드 조각이 있습니다.

actor { 
    loop { 
    react { 
     case SomeEvent => 
     //I want to submit a piece of work to a queue and then send a response 
     //when that is finished. However, I don't want *this* actor to block 
     val params = "Some args" 
     val f: Future[Any] = myQueue.submitWork(params); 
     actor { 
      //await here 
      val response = f.get 
      publisher ! response 
     } 

    } 
    } 
} 

외부 액터가 실제로 SomeEvent 핸들러 내에서 생성 된 별도의 액터에 의해 수행되기 때문에 f.get을 차단하지 않습니다.

이것이 맞습니까?

답변

2

네, 맞습니다. 외부 액터는 단순히 액터를 만들고 일시 중단합니다 (다음 메시지 대기). 그러나, 이런 종류의 것을 아주 조심하십시오. 내부 액터는 스레드에 의해 처리되도록 스케줄러에서 자동으로 시작됩니다. 해당 스레드 은 해당 Future (내게는 java.util.concurrent.Future처럼 보입니다)에서을 차단합니다. 이 작업을 충분히 수행하면 사용 가능한 모든 스레드가 Futures에서 차단되는 기아 문제가 발생할 수 있습니다. 액터는 기본적으로 작업 큐이므로 이러한 의미를 대신 사용해야합니다.

다음은 Scalaz actors library을 사용하는 코드의 버전입니다. 이 라이브러리는 표준 스칼라 액터보다 훨씬 간단하고 이해하기 쉽습니다 (소스는 말 그대로 페이지와 반입니다). 또한 훨씬 더 간결한 코드로 연결됩니다.

actor {(e: SomeEvent) => promise { ... } to publisher } 

이 버전은 완전히 차단되지 않습니다.

+0

하지만 대기열에 작업을 보내고 (juc) Future를 얻는다면 대기열 API를 제어하지 않는 경우 (예 : 다시 구현할 수없는 경우) 차단을 피할 수 있습니까? 작업 완료시 게시자에게 이벤트가 제공되도록 작업 대기열)? –

+0

작업 대기열에 임의의 코드를 제출할 수 있습니까? 그렇다면, 당신은 당신의 배우 중 한 사람에게 메시지를 보내서 끝나는 Unit - valued 계산을 제출할 수 있습니다. 그리고 단순히 미래를 무시하십시오. [Unit] – Apocalisp

+0

나는 submitWork를 호출 할 때 내가 정확히 무엇을하고 있는지 명확히하기 위해 질문을 편집했습니다. 기본적으로 아니오, 임의의 실행 파일/호출 가능 파일을 제출할 수 없습니다. 그러나 모든 코드를 원래 작성 했으므로 API를 변경해야합니다 (예 : –

관련 문제