diff options
author | phaller <hallerp@gmail.com> | 2012-08-05 00:20:01 +0200 |
---|---|---|
committer | phaller <hallerp@gmail.com> | 2012-08-05 00:20:01 +0200 |
commit | 5b82a9702de3ffd5b131caf8c550877b476e8f9c (patch) | |
tree | 86c8e93115815b8b6aa8b2322d0dc33cb26bfcd5 /test/files/jvm | |
parent | 3cb0e784a05db7d0b542cec9bf4c5fbf3772a6cf (diff) | |
download | scala-5b82a9702de3ffd5b131caf8c550877b476e8f9c.tar.gz scala-5b82a9702de3ffd5b131caf8c550877b476e8f9c.tar.bz2 scala-5b82a9702de3ffd5b131caf8c550877b476e8f9c.zip |
SI-6185 - add "prepare" hook to ExecutionContext
Enables important abstractions to be built on top of futures,
such as Twitter's "Local" for handling data local to a callback chain.
Diffstat (limited to 'test/files/jvm')
-rw-r--r-- | test/files/jvm/scala-concurrent-tck.scala | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/test/files/jvm/scala-concurrent-tck.scala b/test/files/jvm/scala-concurrent-tck.scala index 36ab910593..976d98a337 100644 --- a/test/files/jvm/scala-concurrent-tck.scala +++ b/test/files/jvm/scala-concurrent-tck.scala @@ -926,6 +926,66 @@ trait CustomExecutionContext extends TestBase { testCallbackChainCustomEC() } +trait ExecutionContextPrepare extends TestBase { + val theLocal = new ThreadLocal[String] { + override protected def initialValue(): String = "" + } + + class PreparingExecutionContext extends ExecutionContext { + def delegate = ExecutionContext.global + + override def execute(runnable: Runnable): Unit = + delegate.execute(runnable) + + override def prepare[T, U](f: Try[T] => U): ExecutionContext = { + // save object stored in ThreadLocal storage + val localData = theLocal.get + new PreparingExecutionContext { + override def execute(runnable: Runnable): Unit = { + val wrapper = new Runnable { + override def run(): Unit = { + // now we're on the new thread + // put localData into theLocal + theLocal.set(localData) + runnable.run() + } + } + delegate.execute(wrapper) + } + } + } + + override def reportFailure(t: Throwable): Unit = + delegate.reportFailure(t) + } + + implicit val ec = new PreparingExecutionContext + + def testOnComplete(): Unit = once { + done => + theLocal.set("secret") + val fut = future { 42 } + fut onComplete { + case _ => + assert(theLocal.get == "secret") + done() + } + } + + def testMap(): Unit = once { + done => + theLocal.set("secret2") + val fut = future { 42 } + fut map { x => + assert(theLocal.get == "secret2") + done() + } + } + + testOnComplete() + testMap() +} + object Test extends App with FutureCallbacks @@ -935,6 +995,7 @@ with Promises with BlockContexts with Exceptions with CustomExecutionContext +with ExecutionContextPrepare { System.exit(0) } |