Skip to content

Instantly share code, notes, and snippets.

@ograycode
Last active December 20, 2015 14:38
Show Gist options
  • Select an option

  • Save ograycode/6147609 to your computer and use it in GitHub Desktop.

Select an option

Save ograycode/6147609 to your computer and use it in GitHub Desktop.
Play 2.1.2 message passing in Akka. This is from the application controller. Half the imports here probably are not used.
package controllers
import akka.actor.Props
import akka.actor._
import akka.actor
import akka.pattern._
import akka.util._
import akka.event._
import scala.concurrent.Await
import scala.concurrent.Future
import play.api.libs.concurrent.Akka
import play.api.libs.concurrent.Akka._
import play.api.Play.current
import play.api._
import play.api.libs.concurrent.Execution.Implicits._
import play.api.mvc._
import scala.collection.immutable._
import scala.concurrent.duration._
object Application extends Controller {
println("Starting actors")
val actorSupervisor = Akka.system.actorOf(Props[ActorSupervisor], name = "supervisor")
implicit val timeout = Timeout(6 seconds)
def index = Action {
val future = actorSupervisor ? new Message("test")
val result = Await.result(future, 5.seconds).asInstanceOf[Message]
Ok(views.html.index(result.msg))
}
}
case class Message (val msg: String)
case class MessageWithOriginalSender(val msg: String, val originalSender: ActorRef)
class ActorSupervisor extends Actor {
val log = Logging(context.system, this)
var workers = Vector[ActorRef]()
createWorks
def createWorks = {
val workerNames = Vector[String]("worker-1", "worker-2", "worker-3")
for (name <- workerNames) {
workers = workers :+ context.actorOf(Props[ActorWorker], name = name)
}
}
//Naive round robin routing
var currentWorker = -1
def nextWorker = {
log.info("Worker size: " + workers.size)
if (currentWorker >= workers.size - 1) {
currentWorker = 0
} else {
currentWorker = currentWorker + 1
}
workers(currentWorker)
}
def receive = {
case Message(msg) =>
log.info("Sending message")
nextWorker ! new MessageWithOriginalSender(msg, sender)
case _ =>
log.info("received unknown message")
sender ! new Message("unknown")
}
}
//Second level of actor which will pass a message back up the chain.
class ActorWorker extends Actor {
def receive = {
case MessageWithOriginalSender(msg, originalSender) =>
originalSender ! new Message(self.path.name)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment