2014-04-23 3 views
6

Spray.io 프레임 워크를 사용하여 REST 서비스를 구현합니다. 이러한 서비스는 일부 "검색"쿼리를 받아 처리하고 결과를 다시 클라이언트에 보내야합니다. 별도의 액터 - SearchActor에있는 perfrom 검색 코드는 사용자로부터 JSON 쿼리를받은 후 askActor에게이 쿼리를 다시 보냅니다 (ask 패턴 사용). 하지만 내가 실제로 스프레이와 루트 액터와 SearchActor 사이의 상호 작용을 어떻게 구현해야하는지 이해하지 못합니다.Spray.io - 다른 액터로 처리 위임

여러 가지 변형을 볼 수 있지만 어느 것이 더 정확하고 왜 그런가요?

  1. 만들 SearchActor의 새로운 인스턴스를 시작할 때 SearchActor의 인스턴스를 생성하고 모든 요청에 ​​대해이 배우
  2. 에 모든 요청을 보내
  3. 시작시 SearchActor 배우의 풀을 만들고이 풀에 요청을 보낼

답변

2

강요 패턴을 사용하지 않아도됩니다. 사실, 각 요청에 대한 스레드가 생성되며 이것은 아마도이 원하는 것이 아닙니다. 대신 tell을 사용하는 것이 좋습니다. 생성자 필드 중 하나에 RequestContext이있는 각 요청 (은 스레드보다 비싸지 않음)마다 새 Actor을 생성하여이 작업을 수행합니다. 이 컨텍스트를 사용하여 일반적으로 complete 메소드를 사용하여 응답을 되돌립니다.

예제 코드.

class RESTActor extends HttpService { 
    val route = path("mypath") ~ post { 
    entity(as[SearchActor.Search]) { search => ctx => 
     SearchActor(ctx) ! search 
    } 
    } 
} 

case class SearchActor(ctx: RequestContext) { 
    def receive = { 
    case msg: Search => //... search process 
    case msg: Result => ctx.complete(msg) // sends back reply 
    } 
} 
+0

> WAT "는 스레드를 생성합니다"에 표시됩니다 ?? – ZhekaKozlov

+0

Akka doc => ask에 대한 몇 가지 설명 : 메시지에 대한 회신을 받고 자신과 함께 scala.concurrent.Future를 완료 할 수있는 일시적인 일회용 액터를 만듭니다. 미래를 되 돌린다. 그리고 스프레이는 지시문에 선물을 처리합니다. 따라서 스레드를 생성하지 않습니다. 위의 방법은 ask 패턴을 사용하는 것과 매우 유사합니다. 비즈니스 논리를 작성하려는 위치에 따라 다릅니다. – Leo

+0

안내/의견 차이에 대한 흥미로운 토론 => https://groups.google.com/forum/#!topic/akka-user/GlMq6J4ZlAc – Leo

1

변형 1 번은 처음 구현 후 문제가됩니다. 수평 확장을 원할 경우 단일 차단 액터가 좋지 않습니다.

변형 2와 3은별로 다르지 않습니다. 새 액터를 만드는 것이 저렴하고 최소한의 오버 헤드가 있습니다. 배우가 자주 죽을 수 있으므로 (예 : 백엔드를 사용할 수 없음), # 2가 갈 길이라고합니다.

콘크리트 구현 아이디어는 http://techblog.net-a-porter.com/2013/12/ask-tell-and-per-request-actors/

관련 문제