I'm attempting to test out Akka with Play 2.5 and I'm running into a compile error I can't seem to get around.
I'm following this page from the Play docs: https://playframework.com/documentation/2.5.x/ScalaAkka
Here is the full code:
package controllers
import javax.inject.{Inject, Singleton}
import akka.actor.ActorSystem
import controllers.HelloActor.SayHello
import play.api.mvc._
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import scala.concurrent.duration._
import akka.pattern.ask
@Singleton
class Application @Inject()(system: ActorSystem) extends Controller {
implicit val timeout = 5.seconds
val helloActor = system.actorOf(HelloActor.props, "hello-actor")
def sayHello(name: String) = Action.async {
(helloActor ? SayHello(name)).mapTo[String].map { message =>
Ok(message)
}
}
}
import akka.actor._
object HelloActor {
def props = Props[HelloActor]
case class SayHello(name: String)
}
class HelloActor extends Actor {
import HelloActor._
def receive = {
case SayHello(name: String) =>
sender() ! "Hello, " + name
}
}
My route looks like:
GET /:name controllers.Application.sayHello(name: String)
And, finally, my build.sbt:
name := "AkkaTest"
version := "1.0"
lazy val `akkatest` = (project in file(".")).enablePlugins(PlayScala)
scalaVersion := "2.11.7"
libraryDependencies ++= Seq( jdbc , cache , ws , specs2 % Test )
unmanagedResourceDirectories in Test <+= baseDirectory ( _ /"target/web/public/test" )
resolvers += "scalaz-bintray" at "https://dl.bintray.com/scalaz/releases"
routesGenerator := InjectedRoutesGenerator
When I attempt to run this, I get the following compilation error:
could not find implicit value for parameter timeout: akka.util.Timeout
I've tried moving around the timeout to no avail. Does anyone have an idea what might cause this compilation error?
You getting this error because the ask pattern requires an implicit timeout for asking (it will complete future with TimeoutException
if no answer was received for this time). So all you need is to create an implicit local value in sayHello
method like this:
import akka.util.Timeout
import scala.concurrent.duration.Duration
// ...
def sayHello(name: String) = Action.async {
implicit val timeout: Timeout = Duration.Infinite
(helloActor ? SayHello(name)).mapTo[String].map { message =>
Ok(message)
}
}
Instead of specifying infinite timeout you can specifiy a finite one with following syntax:
import scala.concurrent.duration._
import akka.util.Timeout
implicit val duration: Timeout = 20 seconds
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With