Blankman
Blankman

Reputation: 266900

Setting up akka in playframework, how to configure and get hold of ActorSystem?

I'm trying to create a simple akka setup in my play application.

import akka.actor._
import akka.event.Logging
class HelloActor extends Actor with ActorLogging{
  def receive = {
    case "hello" => log.info("hello received")
    case _ => log.info("catch call received")
  }
}

I have read that I should create my ActorSystem in global, but should I be creating a singleton to hold the reference?

Global.scala

override def onStart(app: Application) {
  // ???
}

I have a simple json endpoint in my play application, so whenever that api endpoint gets called I want to pass the message to my akka actor.

I am basically creating an akka system build around play so it can be sent messages over http.

// /testAkka/
def testAkka = Action(BodyParsers.parse.json) { request =>

    val message1Result = request.body.validate[Message1]
    message1Result.fold(
      errors => {
        BadRequest(Json.obj("status" -> "KO", "message" -> JsError.toFlatJson(errors)))
      },
       msg1 => {
         val helloActor = system.actorOf(Props(new HelloActor("Fred")), name = "helloactor")
         helloActor ! msg1.name
         Ok(Json.toJson(msg1))
       }
    )
  }

Note: I don't want to use the default akka system in play, I need to create my own in application.conf

**How will should I create my ActorSystem in my onStart method in Global.scala and how will I reference this in my Controller? Also, is there an example application.conf setup for play 2.2.3? **

Upvotes: 3

Views: 1414

Answers (1)

ale64bit
ale64bit

Reputation: 6242

First, you can define your Global.scala inside the common package as follows (it cannot be in the default package since you wouldn't be able to access that class):

import play.api._

package common

object Global extends GlobalSettings {

  val mySystem = ActorSystem("my-system")

  override def onStart(app: Application) {
    // initialize your stuff here
  }

}

Then you can use that system in your controllers as in:

def testAkka = Action(BodyParsers.parse.json) { request =>

    val message1Result = request.body.validate[Message1]
    message1Result.fold(
      errors => {
        BadRequest(Json.obj("status" -> "KO", "message" -> JsError.toFlatJson(errors)))
      },
       msg1 => {
         val helloActor = Global.mySystem.actorOf(Props(new HelloActor("Fred")), name = "helloactor")
         helloActor ! msg1.name
         Ok(Json.toJson(msg1))
       }
    )
  }

Finally, you have to tweak your application.conf and specify that your Global.scala is in a non-default location:

global=common.Global

Although I'm not very sure, if in Play 2.2.x you may have to write:

application.global=common.Global

Hope it helped )

Upvotes: 2

Related Questions