views:

276

answers:

2

I have a Scala application using Akka that receives REST requests, makes some operations against a database, and responds with some information to the client. As it is, my db operations take a long time and my REST-enabled actor is unable to respond to new requests in the meantime, even though I could run lots of operations concurrently against the DB. I'm using the javax.ws.rs annotations to REST-enable methods in my actor.

The question; what is the best way to enable my application to handle a large number of concurrent requests?

EDIT: I'll add some sample code.

  import se.scalablesolutions.akka.actor._
  import javax.ws.rs._

  @Path("/test")
  class TestService {

    @GET
    def status() = 
      actorPool !! Status(session).
        getOrElse(<error>Unable to connect to service</error>)
  }

  class TestActor {

    def receive = {
      case Status() => {
        reply(SomeObject.slowDBMethod)
      }
    }
  }

  case class Status()

EDIT2: This is what I'm getting in the log. I'm sending the three requests from my browser as fast as I can switch tabs and press F5, but the RS bean still waits for the first request to complete before handling the next.

[INFO] [2010-08-29 16:27:03,232] [akka:event-driven:dispatcher:global-15] c.n.StatusActor: got Slow request
[INFO] [2010-08-29 16:27:06,916] [akka:event-driven:dispatcher:global-10] c.n.StatusActor: got Slow request
[INFO] [2010-08-29 16:27:10,589] [akka:event-driven:dispatcher:global-3] c.n.StatusActor: got Slow request
+3  A: 

Once you get a request, you should create a new actor to handle that request. Pass on the original sender so the newly created actor knows who to answer to.

Daniel
In a 'normal' actor situation, I would expect that to work. But in my case I can't really pass on the "sender" in the status() method of the added code sample? I assume that whatever I do in the receive method the actor won't be ready for more REST requests as long as the status() method hasn't completed.
Magnus
How about keeping actor per user session?
andreypopp
+5  A: 

Hey Magnus,

you seem to be using an older version of Akka.

I recommend to upgrade to 0.10 (which separates Actors and the RS-Beans), then you can use LoadBalancer1 (and2) to throttle the workload, or take advantage of the WorkStealingDispatcher3 (and4)

Does that help?

Viktor Klang
That looks promising. I'll try out 0.10.
Magnus
I couldn't find a 0.10 version of akka-rest, at least in the maven2 repository. Should I use the 0.8 version?
Magnus
@Magnus See http://doc.akkasource.org/getting-started#The%20Next%20Steps-Using%20Akka%20with%20Maven
Aaron Novstrup
I did all that. Upgraded to 0.10 and implemented a load balancer. However, my RS-beans still seem to handle requests in sequence. Since most requests are waiting for a slow backend operations, new requests are almost always stalled. This happens even though the requests seem to be handled by different threads. See edited question for log entries.
Magnus
Hey Magnus, this should be solved in Akka master. Jettys QueuedThreadPool was at fault.
Viktor Klang