Completion is non-atomic between the two promises.
When either promise successfully completes, it will attempt to synchronously complete its counterpart with the same value. This will succeed barring a race with cancellation.
When either promise completes with an Exception, it will attempt to synchronously complete its counterpart with the same Exception. This will succeed barring a race with cancellation.
Cancellation is propagated bidirectionally.
When the returned Future is successfully cancelled - meaning Future.cancel returned true -
Deferred.cancel will be synchronously called on
this Deferred. This will attempt to cancel
Deferred, though cancellation may not succeed and the
Deferred may complete in a
non-cancelled terminal state.
Deferred reaches its “cancelled” state with a successful cancellation - meaning it
completes with kotlinx.coroutines.CancellationException -
Deferred will synchronously
cancel the returned
Future. This can only race with cancellation of the returned
Future will always eventually reach its cancelled state when either promise is
successfully cancelled, for their different meanings of “successfully cancelled”.
This is inherently a race. See Future.cancel for a description of
semantics. See Job for a description of coroutine cancellation semantics. See
DeferredListenableFuture.cancel for greater detail on the overlapped cancellation semantics and
corner cases of this method.