Skip to content

Add Scala 2.12.0-M2 as a cross build #46

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 13, 2015
Merged

Conversation

retronym
Copy link
Member

No description provided.

@retronym
Copy link
Member Author

Review by @rkuhn or @viktorklang

retronym referenced this pull request in scala/scala Jul 28, 2015
  - `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
@retronym retronym modified the milestone: 0.5.0 Jul 28, 2015
@retronym retronym force-pushed the topic/add212 branch 4 times, most recently from c374b83 to 770a59a Compare July 28, 2015 10:48
retronym added a commit to retronym/scala-java8-compat that referenced this pull request Jul 28, 2015
Makes `toJava.toScala` and `toScala.toJava` a wrap-and-unwrap
operation, rather than a wrap-and-rewrap.

This won't be possible if we merge scala#46, which speaks in favour
of reverting the change that finalized `DefaultPromise` in Scala
2.12.x.

This patch does not attempt to "wrap the Future with an implementation
of CompletionStage that delegates to Future", as Jame's proposed in
issue scala#44, which seems tricky or at least tedious to implement.
@retronym
Copy link
Member Author

Marking as "on-hold" as this would prevent #50. An alternative would be to unfinalize DefaultPromise in 2.11.0-M3

@viktorklang
Copy link

@retronym The reason for final-ing DefaultPromise is to make sure that the optimizer can do its job, avoiding tripping into bimorphic or megamorphic callsites. I think the extra allocation and indirection in your proposal is OK given that, but also to prevent others from extending it. Wdyt?

@retronym
Copy link
Member Author

@viktorklang Can you see a way to implement #50 if DefaultPromise if final? That PR needs to carry around an extra field in the promise: the wrapped Java completion stage. The only solution I see is to copy/paste its implementation.

@retronym
Copy link
Member Author

We could mark a selection of methods like isCompleted and value as final DefaultPromise to keep them bimorphic (KeptPromise also implements them).

@viktorklang
Copy link

@retronym Perhaps an option would be to make all of the methods on DefaultPromise final?

@retronym
Copy link
Member Author

Yeah, I'm fine with that.

@viktorklang
Copy link

@retronym We also need to audit the methods to make sure that nothing will break (is there something that assumes no inheritance?) as well as make sure that methods that may have harmful effects if called from inheriters(?) will be either hidden or appropriately documented.

@retronym
Copy link
Member Author

Yep, changing modifiers is subtle. Could you review your addition of the finality to confirm it was done solely for non functional reasons?

@retronym
Copy link
Member Author

I don't think we need to lock it down to much as it is the whole class already access restricted. If someone plays a trick to subvert that (as we do here) we assume they are responsible for the consequences

@viktorklang
Copy link

I can review the addition at the earliest next week :/

@2m
Copy link
Contributor

2m commented Aug 4, 2015

Released latest genjavadoc (which is 0.9) for scala 2.12.0-M2. Can you update to 0.9 and keep the build clean of scala version switch statements? :) I tried it locally and there seems to be no problems when using 0.9.

@retronym
Copy link
Member Author

ping @viktorklang for assessment on the impact of unfinalizing DefaultPromise.

Avoid inheritance from DefaultPromise, which is final in 2.12.
@retronym
Copy link
Member Author

@2m Thanks for that. I've updated this PR to use 0.9 of genjavadoc in both 2.11 and 2.12.

@viktorklang
Copy link

@retronym I only had time for a cursory overview, it seems as unfinalizing it will be fine. May be in order to final-ize all of its methods tho.

retronym added a commit to retronym/scala that referenced this pull request Aug 13, 2015
Doing so seems like the cleanest way to enabled conversions like
`javaFuture.toScala.toJava` to return the original `javaFuture`
in scala-java8-compat.

I have made the methods defined in this class final as an
alternative lockdown.

Discussion, Motivation:

  scala/scala-java8-compat#46
  scala/scala-java8-compat#50
retronym added a commit to retronym/scala that referenced this pull request Aug 13, 2015
It was non-final in Scala 2.11.x, and made final as part
of fa0743c.

Removing the final modifier seems like the cleanest way to enable
conversions like `javaFuture.toScala.toJava` to return the original
`javaFuture` in scala-java8-compat.

I have made the methods defined in this class final as an
alternative lockdown.

Discussion, Motivation:

  scala/scala-java8-compat#46
  scala/scala-java8-compat#50
retronym added a commit that referenced this pull request Aug 13, 2015
Add Scala 2.12.0-M2 as a cross build
@retronym retronym merged commit 416fe31 into scala:master Aug 13, 2015
@retronym retronym added task and removed on-hold labels Aug 13, 2015
@retronym retronym modified the milestones: 0.5.0, 0.6.0 Aug 13, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants