Reputation: 8195
I'm trying to follow the instructions to create a Play Framework async controller. So far my code is little more than a cut & paste from the Play documentation:
package controllers
import akka.actor.ActorSystem
import com.google.inject.Inject
import play.api.libs.concurrent.CustomExecutionContext
import play.api.mvc.{AbstractController, ControllerComponents}
import scala.concurrent.{ExecutionContext, Future}
trait MyExecutionContext extends ExecutionContext
class MyExecutionContextImpl @Inject()(system: ActorSystem)
extends CustomExecutionContext(system, "my.executor") with MyExecutionContext
class FooController @Inject() (myExecutionContext: MyExecutionContext, cc:ControllerComponents) extends AbstractController(cc) {
def foo = Action.async(
Future {
// Call some blocking API
Ok("result of blocking call")
}(myExecutionContext)
)
}
When I try to run this new controller, I get the following error:
ProvisionException: Unable to provision, see the following errors:
1) No implementation for controllers.MyExecutionContext was bound.
while locating controllers.MyExecutionContext
for the 1st parameter of controllers.FooController.<init>(FooController.scala:14)
while locating controllers.FooController
for the 4th parameter of router.Routes.<init>(Routes.scala:33)
while locating router.Routes
while locating play.api.inject.RoutesProvider
Can anybody explain what might be going wrong here?
Upvotes: 1
Views: 1120
Reputation: 917
The previous answer does not work. Try instead using @ImplementedBy
(source: https://stackoverflow.com/a/53162884/4965515)
In addition you will need to configure your executor in conf/application.conf. For instance try adding:
my.executor {
type = Dispatcher
executor = "thread-pool-executor"
thread-pool-executor {
core-pool-size-factor = 10.0
core-pool-size-max = 10
}
}
(source https://stackoverflow.com/a/46013937/4965515)
Upvotes: 1
Reputation: 14803
The exception indicates that you have not bound the implementation (MyExecutionContext
) to the trait (MyExecutionContextImpl
) in your Module.
Try this:
class Module extends AbstractModule {
override def configure(): Unit = {
bind(classOf[MyExecutionContext])
.to(classOf[MyExecutionContextImpl])
}
}
However I never used your approach. I use only the default Execution Context like:
class FooController @Inject()()(implicit val ec: ExecutionContext)
Upvotes: 1