Spray.io - delegate processing to another actor(s)
Asked Answered
D

2

6

I implement a REST service using Spray.io framework. Such service must receive some "search" queries, process them and send result back to the client(s). The code that perfrom searching located in separate actor - SearchActor, so after receiving (JSON) query from user, i re-send (using ask pattern) this query to my SearchActor. But what i don't really understand it's how i must implement interaction between spray.io route actor and my SearchActor.

I see here several variants but which one is more correct and why?

  1. Create one instance of SearchActor at startup and send every request to this actor
  2. For every request create new instance of SearchActor
  3. Create pool of SearchActor actors at startup and send requests to this pool
Dickinson answered 23/4, 2014 at 20:43 Comment(0)
O
2

You're not forced to use the ask pattern. In fact, it will create a thread for each of your request and this is probably not what you want. I would recommend that you use a tell instead. You do this by spawning a new Actor for each request (less expensive than a thread), that has the RequestContext in one of its constructor fields. You will use this context to give the response back, typically with its complete method.

Example code.

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
  }
}
Orford answered 24/4, 2014 at 2:30 Comment(2)
Some clarification from Akka doc => ask: create a temporary one-off actor for receiving a reply to a message and complete a scala.concurrent.Future with it; returns said Future. And Spray handles Futures in its directives. So, no it does not create a thread. And the above approach is pretty similar to using the ask pattern. It depends on where you want to write your business logic.Orford
Interesting discussion about tell/ask differences => groups.google.com/forum/#!topic/akka-user/GlMq6J4ZlAcOrford
D
1

Variant #1 is out of question after the initial implementation - you would want to scale out, so single blocking actor is bad.

Variants #2 and #3 are not very different - creation of new actor is cheap and has minimal overhead. As your actors may die often (i.e. backend is not available), i would say that #2 is the way to go.

Concrete implementation idea is shown at http://techblog.net-a-porter.com/2013/12/ask-tell-and-per-request-actors/

Disburse answered 24/4, 2014 at 2:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.