Play Framework 2.1 - Cannot find an implicit ExecutionContext
Asked Answered
B

2

49

I am calling a webservice like this:

WS
  .url(url)
  .get
  .map { response => // error occurs on this line
    response.status match {
      case 200 => Right(response.json)
      case status => Left(s"Problem accessing api, status '$status'")
  }
}

The complete error: Error: Cannot find an implicit ExecutionContext, either require one yourself or import ExecutionContext.Implicits.global

Broider answered 19/2, 2013 at 15:56 Comment(0)
B
114

According to this issue, it is fixed in the documentation. I needed to add the following import:

import play.api.libs.concurrent.Execution.Implicits._
Broider answered 19/2, 2013 at 15:56 Comment(7)
About the execution context. Some people think it's the same thing as the Scala global context. It however is not. Execution.scala is pointing to Invoker.scala So it actually is the execution context of the Play actor system. This allows you to change behavior using the application.confBroider
The "This issue" link is broken now. There is an archive on the web.archive though: web.archive.org/web/20140222113140/http://…Washbasin
@Washbasin Thank you, I have adjusted the linkBroider
link broken againFettling
@Fettling Thanks for reporting. Too bad the internet does not have persistent links.Broider
I'd say it's more correct to inject it from the injection framework as indicated below. particularly given that this is the way the example apps manage it.Lex
Since play 2.6 you should use Guice dependency injection #14962208Allysonalma
A
2

Since Play 2.6 it's recommended to use guice dependency injection for execution context.

Default execution context injection:

Foo.scala

class Foo @Inject()()(implicit ec:ExecutionContext) {

def bar() = {
   WS.url(url)
     .get
     .map { response => // error occurs on this line
       response.status match {
         case 200 => Right(response.json)
         case status => Left(s"Problem accessing api, status '$status'")
     }
   }
}

Custom execution context injection:

application.conf

# db connections = ((physical_core_count * 2) + effective_spindle_count)
fixedConnectionPool = 9

database.dispatcher {
  executor = "thread-pool-executor"
  throughput = 1
  thread-pool-executor {
    fixed-pool-size = ${fixedConnectionPool}
  }
}

DatabaseExecutionContext.scala

@Singleton 
class DatabaseExecutionContext @Inject()(system: ActorSystem) extends CustomExecutionContext(system,"database.dispatcher")

Foo.scala

class Foo @Inject()(implicit executionContext: DatabaseExecutionContext ) {   ...    }

More info at:

https://www.playframework.com/documentation/2.6.x/Migration26#play.api.libs.concurrent.Execution-is-deprecated https://www.playframework.com/documentation/2.6.x/Highlights26#CustomExecutionContext-and-Thread-Pool-Sizing

Allysonalma answered 16/5, 2016 at 23:25 Comment(3)
Your code does not inject the execution context. It still uses implicit resolution to get the execution context.Broider
As per Play documentation (at least 2.6), @mgosk's answer is the standard; see: playframework.com/documentation/2.6.x/…Glassman
There is, however, more to it. You can extend/define CustomExecutionContext too. See: playframework.com/documentation/2.6.x/… and playframework.com/documentation/2.6.x/…Glassman

© 2022 - 2024 — McMap. All rights reserved.