Reputation: 3435
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
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.
As @Alexey Romanov points out, this GitHub issue points out the reason for this deprecation:
Calling
completeWith
when theDefaultPromise
is already completed, leads to callbacks not being properly executed.This happened because
Future.InternalCallbackExecutor
extendsBatchingExecutor
which assumesunbatchedExecute
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 tounbatchedExecute
and then rethrows, but if you have a syncunbatchedExecute
, it will fail since it is not reentrant, as witnessed by the failedrequire
as reported in this issue.This commit avoids problem by delegating
completeWith
totryComplete
, which has the effect of usingonComplete
+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