diff options
author | Viktor Klang <viktor.klang@gmail.com> | 2014-09-26 12:05:37 +0200 |
---|---|---|
committer | Viktor Klang <viktor.klang@gmail.com> | 2014-10-20 23:55:44 +0200 |
commit | fa0743c32338f147eaf7a5d69566bbc15d193f85 (patch) | |
tree | 24f6b6d5cbab337174d48f0d0876ac0de93141f5 /src/library/scala/concurrent/ExecutionContext.scala | |
parent | c0ceffb865ff4b2146aacec547cc42bb7605ee93 (diff) | |
download | scala-fa0743c32338f147eaf7a5d69566bbc15d193f85.tar.gz scala-fa0743c32338f147eaf7a5d69566bbc15d193f85.tar.bz2 scala-fa0743c32338f147eaf7a5d69566bbc15d193f85.zip |
Add missing canonical combinators:
- `def transform[S](f: Try[T] => Try[S])(implicit executor: ExecutionContext): Future[S]`
- `def transformWith[S](f: Try[T] => Future[S])(implicit executor: ExecutionContext): Future[S]`
- `def flatten[S](implicit ev: T <:< Future[S]): Future[S]`
- `def zipWith[U, R](that: Future[U])(f: (T, U) => R)(implicit executor: ExecutionContext): Future[R]`
Add missing utilities:
- `val unit: Future[Unit]` in `object Future`
- `object never extends Future[Nothing]` in `object Future`
- `def defaultBlockContext: BlockContext` in `object BlockContext`
- `def toString: String` on stdlib implementations of `Future`
Refactors:
- the `scala.concurrent.Future` trait to not explicit create any `Promises`,
so that implementations can control implementation type,
this is mainly facilitated through adding of the `transform` and `transformWith` methods.
- the implementation of `ExecutionContextImpl` has been cleaned up
- the `scala.concurrent.impl.DefaultPromise` has been reimplemented to not use `sun.misc.Unsafe`
Securing:
- Add a self-check in `completeWith` and `tryCompleteWith` to avoid cycles in trait Promise
- Capping the maximum number of threads for the global `ExecutionContext` to the max parallelism
- Implementing (almost) all `Future` combinators on `transformWith` and `transform` means
that `DefaultPromise` linking works on both `(flat)map` and `recover(With)`
- Nested `blocking {}` should not spawn extra threads beyond the first.
Removes:
- the private `internalExecutor` method in favor of an import in trait `Future`
- the private `internalExecutor` method in favor of an import in trait `Promise`
- the `AtomicReferenceFieldUpdater` in `AbstractPromise` since we're using `Unsafe`
- `scala.concurrent.impl.Future` is no longer needed
Deprecates:
- `Future.onSuccess` - discourage the use of callbacks
(and is also redundant considering `foreach` and `onComplete`)
- `Future.onFailure` - discourage the use of callbacks
(and is also redundant considering `onComplete` and `failed.foreach`)
- `ExecutionContext.prepare` - it was ill specced and it is too easy to forget to call it
(or even know when to call it or call it more times than needed)
- All classes in scala.concurrent.forkjoin. Scala 2.12 will be Java 8+ and as such the jsr166e
should be used as included in java.util.concurrent.
Reimplements:
- `failed` - in terms of `transform`
- `map` - in terms of `transform`
- `flatMap` - in terms of `transformWith`
- `recover` - in terms of `transform`
- `recoverWith` - in terms of `transformWith`
- `zip` - in terms of `flatMap` + `map`
- `fallbackTo` - in terms of `recoverWith` + `recoverWith`
- `andThen` - in terms of `transform`
Miscellaneous:
- Giving the threads of `ExecutionContext.global` sensible names
- Optimizes `object Future.successful` and `object Future.failed` are now separate implementations,
to optimize for the result, avoiding doing work for the "other branch".
- Optimizes `compressedRoot()` by avoiding double-calls to volatile get.
Documentation:
- Almost all methods on `Future` and `Promise` have been revisited and had their ScalaDoc updated
Tests:
- Yes
Diffstat (limited to 'src/library/scala/concurrent/ExecutionContext.scala')
-rw-r--r-- | src/library/scala/concurrent/ExecutionContext.scala | 32 |
1 files changed, 17 insertions, 15 deletions
diff --git a/src/library/scala/concurrent/ExecutionContext.scala b/src/library/scala/concurrent/ExecutionContext.scala index 11d3bb8b02..0bb96b5b30 100644 --- a/src/library/scala/concurrent/ExecutionContext.scala +++ b/src/library/scala/concurrent/ExecutionContext.scala @@ -72,22 +72,24 @@ trait ExecutionContext { */ def reportFailure(@deprecatedName('t) cause: Throwable): Unit - /** Prepares for the execution of a task. Returns the prepared execution context. - * - * `prepare` should be called at the site where an `ExecutionContext` is received (for - * example, through an implicit method parameter). The returned execution context may - * then be used to execute tasks. The role of `prepare` is to save any context relevant - * to an execution's ''call site'', so that this context may be restored at the - * ''execution site''. (These are often different: for example, execution may be - * suspended through a `Promise`'s future until the `Promise` is completed, which may - * be done in another thread, on another stack.) - * - * Note: a valid implementation of `prepare` is one that simply returns `this`. - * - * @return the prepared execution context - */ + /** Prepares for the execution of a task. Returns the prepared + * execution context. The recommended implementation of + * `prepare` is to return `this`. + * + * This method should no longer be overridden or called. It was + * originally expected that `prepare` would be called by + * all libraries that consume ExecutionContexts, in order to + * capture thread local context. However, this usage has proven + * difficult to implement in practice and instead it is + * now better to avoid using `prepare` entirely. + * + * Instead, if an `ExecutionContext` needs to capture thread + * local context, it should capture that context when it is + * constructed, so that it doesn't need any additional + * preparation later. + */ + @deprecated("Preparation of ExecutionContexts will be removed.", "2.12") def prepare(): ExecutionContext = this - } /** |