Alexander Arendar
Alexander Arendar

Reputation: 3435

How does Promise.completeWith differ from Promise.tryCompleteWith?

scala.concurrent.Promise

I tried to find out the difference between completeWith and tryCompleteWith in scaladoc but there is not much explanation and no examples. Also I'm afraid reading the source code with my current level of expertize could mislead me. Need your advice guys with some examples.

Upvotes: 3

Views: 379

Answers (1)

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149558

Promise.completeWith is just a wrapper which calls Promise.tryCompleteWith:

/** Completes this promise with the specified future, once that future is completed.
 *
 *  @return   This promise
 */
final def completeWith(other: Future[T]): this.type = tryCompleteWith(other)

/** Attempts to complete this promise with the specified future, once that future is completed.
 *
 *  @return   This promise
 */
final def tryCompleteWith(other: Future[T]): this.type = {
    other onComplete { this tryComplete _ }
    this
}

To be honest I don't know why they made that decision as it looks like a simple wrapper, nothing more.

Edit

As @Alexey Romanov points out, this GitHub issue points out the reason for this deprecation:

Calling completeWith when the DefaultPromise is already completed, leads to callbacks not being properly executed.

This happened because Future.InternalCallbackExecutor extends BatchingExecutor which assumes unbatchedExecute to be async, when in this case it is sync, and if there is an exception thrown by executing the batch, it creates a new batch with the remaining items from the current batch and submits that to unbatchedExecute and then rethrows, but if you have a sync unbatchedExecute, it will fail since it is not reentrant, as witnessed by the failed require as reported in this issue.

This commit avoids problem by delegating completeWith to tryComplete, which has the effect of using onComplete + tryComplete i.s.o. complete, which means that when it fails (because of a benign race condition between completers) it won't throw an exception.

Upvotes: 4

Related Questions