Gangstead
Gangstead

Reputation: 4182

How to have separate long lived pool of actors for business layer in Spray application?

I'm creating a RESTful API with Spray 1.2.0 and Akka 2.2.3. Scala version is 2.10 (all of these versions can be changed if necessary). In my business layer I have to communicate over SSH connections to a legacy system. These connections take a long time (1 - 3 minutes) to set up and will expire if they are idle for too long. I worked on the SSH code separately on a test app and now I've wrapped it in an actor.

How do I designate a pool of the SSH actors that is separate from the actors Spray uses to handle HTTP requests? I need these actors to be created at startup as opposed to when a request comes in, otherwise the request times out while the connection is being established. Also, how do I control the size of that pool of actors independently of Spray's actors?

Upvotes: 1

Views: 558

Answers (2)

Gangstead
Gangstead

Reputation: 4182

For posterity here is the solution I ended up going with. I define a router actor. This automatically creates instances of my ssh-actors and routes messages to them. I also tell that actor to use a PinnedDispatcher. This dispatcher says that each actor in my router will be run on it's own thread and stay there, which is necessary because Jsch, the Ssh library the ssh-actors depend on, uses blocking io.

The actor ref factory looks a little different from other examples because I'm using spring-scala.

implicit val system = ActorSystem("my-services")

val SshRouter = system.actorOf(Props(SpringExt(system).ctx.getBean(classOf[SshActor]))
    .withRouter(FromConfig())
    .withDispatcher("ssh-actor-dispatcher")
    ,"ssh-actor-router")

Then in application.conf I define the configuration for this router and dispatcher:

akka.actor {
  creation-timeout = 200s
  deployment {
    /ssh-actor-router {
      router = round-robin
      nr-of-instances = 4
    }
  }
}

ssh-actor-dispatcher {
  executor = "thread-pool-executor"
  type = PinnedDispatcher
}

Now I can send messages messages to the router and it forwards it to one of the pool of ssh-actors, which can respond with the output of the command:

(SshRouter ? Execute(cmd)).mapTo[String]

Upvotes: 0

shutty
shutty

Reputation: 3338

How do I designate a pool of the SSH actors that is separate from the actors Spray uses to handle HTTP requests?

You can create a custom dispatcher for this group of actors.

These connections take a long time (1 - 3 minutes) to set up and will expire if they are idle for too long.

You can automatically setup connection on actor startup. Each actor may schedule periodic keep-alive actions not to let the connection to time out using scheduler.

I need these actors to be created at startup. How do I control the size of that pool of actors independently of Spray's actors?

I guess you have to create a required number of these actors manually on app startup.

Upvotes: 2

Related Questions