问题描述:

my environment is scala akka and the play! framework. I was wondering if there is anyway to control the creation of an actor system or any other ideas that can .

My idea is to create remote actors that will handle authorization when a user hits buy. And so, I create the remote actor system and actors in an action method, when a user does a post:

def payment = Action { implicit request =>

var actorObject: Array[String] = new Array[String](23)

val system = ActorSystem("RemoteSystem", ConfigFactory.load.getConfig("remotecreation")

val worker = system.actorOf(Props[authNetActor.AuthNetActorMain].withRouter(FromConfig()), name = "remoteActor")

...

system.shutdown()

}

Here is the definition of remotecreation in the application.conf

remotecreation { #user defined name for the configuration

include "common"

akka {

actor {

serialize-messages = on

serialize-creators = on

serializers {

proto = "akka.serialization.ProtobufSerializer"

java = "akka.serialization.JavaSerializer"

arr = "models.ArraySerializer"

}

serialization-bindings {

"com.google.protobuf.Message" = proto

"java.lang.String" = java

"java.util.Arrays" = java

"scala.Array" = arr

"akka.actor.ActorRef" = java

}

deployment {

/remoteActor { #Specifically has to be the name of the remote actor

remote = "akka://[email protected]:2552"

router = "round-robin"

nr-of-instances = 1

}

}

}

remote.netty.port = 2554

}

}

The problem I am having is that, when I submit twice in a row, I get an error because I am trying to create an actor system on an ip address that already has an actor system on it.

I definitely think I need to move it, but I'm not sure where because since this is going to be a wide, multi user play! application, I'm not sure where I can put the creation of the actor system without being conflicted when hundreds of users use the application.

Any thoughts, suggestions, or help is appreciated.

网友答案:

Don't start a (remote) ActorSystem per call. Instead, start up an application-wide actor system (or use the default one, see integrating Play with Akka).

Add to your application.conf:

akka {

  actor {
    provider = "akka.remote.RemoteActorRefProvider"
  }

  remote {
    transport = "akka.remote.netty.NettyRemoteTransport"
    netty {
      hostname = "127.0.0.1"
      port = 0 # 2552 seems to be bound with play 2.0.2 ?
    }
  }
}

Then use the default Play actorsystem for example to get a reference to the remote actor in your contorller:

private val interpreters = Akka.system.actorFor(
  "akka://[email protected]:2552/user/interpreters")

You might even convert an Akka Future to a Scala Promise if you want to render the actor response. I avice to keep using Akka Futures for composability, then at the very last stem convert the Future[Result] to a Promise.

new AkkaPromise(
  interpreters.ask(InterpretersComm.Request(sid, line)).mapTo[String]) map (Ok(_))
相关阅读:
Top