Reputation: 38217
I'm looking for a non-global instance of the ForkJoinPool
so that I'd get all the great default parallelism and execution semantics of the global instance with the ability to control the life cycle of the pool.
I peeked into the source code of scala.concurrent
and scala.concurrent.impl,
and, sadly, it looks like all of the code that's creating the default instance is private[scala.concurrent]
, and there's no indirect way to call the code either.
I can only get a fresh instance of the ExecutionContext
with default settings using ExecutionContext.fromExecutor(null)
, but there's no way to grab ahold of the underlying ForkJoinPool
. Nor is there a way to shut down an ExecutionContext
directly.
Am I doing something esoteric that I shouldn't be doing? Because to me it seems like a natural thing to want: default semantics/configuration of something without the global'ness of it.
Upvotes: 3
Views: 449
Reputation: 39577
It's not a question of access but of shape. The tail of the elephant:
scala> type ECI = { def createExecutorService: ExecutorService }
defined type alias ECI
scala> val fjp = ExecutionContext.global.asInstanceOf[ECI].createExecutorService
fjp: java.util.concurrent.ExecutorService = scala.concurrent.forkjoin.ForkJoinPool@606dff1[Running, parallelism = 8, size = 0, active = 0, running = 0, steals = 0, tasks = 0, submissions = 0]
or shapelessly:
scala> import shapeless.syntax.typeable._
import shapeless.syntax.typeable._
scala> val fjp = concurrent.ExecutionContext.global.cast[ECI] map (_.createExecutorService) getOrElse ???
fcp: java.util.concurrent.ExecutorService = scala.concurrent.forkjoin.ForkJoinPool@45c26421[Running, parallelism = 8, size = 0, active = 0, running = 0, steals = 0, tasks = 0, submissions = 0]
and then
scala> val eces = ExecutionContext fromExecutorService fjp
eces: scala.concurrent.ExecutionContextExecutorService = scala.concurrent.impl.ExecutionContextImpl$$anon$1@1df3794c
scala> eces.shutdown
Upvotes: 3
Reputation: 508
The good thing about private[path.to.package]
is that you can work around it simply by pretending to be inside that package:
package scala.concurrent
import java.util.concurrent.Executor
object Foo {
implicit lazy val myGlobalExecutionContext: ExecutionContextExecutor =
impl.ExecutionContextImpl.fromExecutor(null: Executor)
}
However, be advised that if you do this, you are not in the realm of public API anymore and will have to deal with certain incompatibilities when you change the scala version.
Upvotes: 3