Skip to content

Commit 6685fd0

Browse files
committed
Abolish distinction between cancelled and failed Job/Deferred
* Job.isCancelled is consistently true on any failure * Deferred.isCompletedExceptionally is deprecated. It is equal to isCancelled && isCompleted * CompletableDeferred.completeExceptionally is deprecated. Use cancel instead. Fixes #220
1 parent f7a6334 commit 6685fd0

32 files changed

+208
-369
lines changed

binary-compatibility-validator/reference-public-api/kotlinx-coroutines-core.txt

+1-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ public abstract class kotlinx/coroutines/experimental/AbstractCoroutine : kotlin
88
protected fun onCancellation (Ljava/lang/Throwable;)V
99
protected fun onCompleted (Ljava/lang/Object;)V
1010
protected fun onCompletedExceptionally (Ljava/lang/Throwable;)V
11-
protected fun onFailing (Ljava/lang/Throwable;)V
1211
protected fun onStart ()V
1312
public final fun resume (Ljava/lang/Object;)V
1413
public final fun resumeWithException (Ljava/lang/Throwable;)V
@@ -383,7 +382,6 @@ public abstract interface class kotlinx/coroutines/experimental/Job : kotlin/cor
383382
public abstract fun isActive ()Z
384383
public abstract fun isCancelled ()Z
385384
public abstract fun isCompleted ()Z
386-
public abstract fun isFailed ()Z
387385
public abstract fun join (Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object;
388386
public abstract fun plus (Lkotlinx/coroutines/experimental/Job;)Lkotlinx/coroutines/experimental/Job;
389387
public abstract fun start ()Z
@@ -455,15 +453,14 @@ public final class kotlinx/coroutines/experimental/NonCancellable : kotlin/corou
455453
public fun isActive ()Z
456454
public fun isCancelled ()Z
457455
public fun isCompleted ()Z
458-
public fun isFailed ()Z
459456
public fun join (Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object;
460457
public fun plus (Lkotlinx/coroutines/experimental/Job;)Lkotlinx/coroutines/experimental/Job;
461458
public fun start ()Z
462459
}
463460

464461
public final class kotlinx/coroutines/experimental/NonDisposableHandle : kotlinx/coroutines/experimental/ChildHandle, kotlinx/coroutines/experimental/DisposableHandle {
465462
public static final field INSTANCE Lkotlinx/coroutines/experimental/NonDisposableHandle;
466-
public fun childFailed (Ljava/lang/Throwable;)Z
463+
public fun childCancelled (Ljava/lang/Throwable;)Z
467464
public fun dispose ()V
468465
public fun toString ()Ljava/lang/String;
469466
}

common/kotlinx-coroutines-core-common/src/AbstractContinuation.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ internal abstract class AbstractContinuation<in T>(
8989
return
9090
}
9191
parent.start() // make sure the parent is started
92-
val handle = parent.invokeOnCompletion(onFailing = true,
92+
val handle = parent.invokeOnCompletion(onCancelling = true,
9393
handler = ChildContinuation(parent, this).asHandler)
9494

9595
parentHandle = handle

common/kotlinx-coroutines-core-common/src/AbstractCoroutine.kt

+6-13
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import kotlin.coroutines.experimental.*
2020
* The following methods are available for override:
2121
*
2222
* * [onStart] is invoked when coroutine is create in not active state and is [started][Job.start].
23-
* * [onFailing] is invoked as soon as coroutine is _failing_, or is cancelled,
23+
* * [onCancellation] is invoked as soon as coroutine is _failing_, or is cancelled,
2424
* or when it completes for any reason.
2525
* * [onCompleted] is invoked when coroutine completes with a value.
2626
* * [onCompletedExceptionally] in invoked when coroutines completes with exception.
@@ -74,24 +74,16 @@ public abstract class AbstractCoroutine<in T>(
7474
}
7575

7676
/**
77-
* @suppress **Deprecated**: Override [onFailing].
78-
*/
79-
@Deprecated("Override onFailing")
80-
protected open fun onCancellation(cause: Throwable?) {}
81-
82-
/**
83-
* This function is invoked once when this coroutine is failing or is completed,
84-
* similarly to [invokeOnCompletion] with `onFailing` set to `true`.
77+
* This function is invoked once when this coroutine is cancelled
78+
* similarly to [invokeOnCompletion] with `onCancelling` set to `true`.
8579
*
8680
* The meaning of [cause] parameter:
8781
* * Cause is `null` when job has completed normally.
8882
* * Cause is an instance of [CancellationException] when job was cancelled _normally_.
8983
* **It should not be treated as an error**. In particular, it should not be reported to error logs.
90-
* * Otherwise, the job had _failed_.
84+
* * Otherwise, the job had been cancelled or failed with exception.
9185
*/
92-
protected override fun onFailing(cause: Throwable?) {
93-
onCancellation(cause)
94-
}
86+
protected override fun onCancellation(cause: Throwable?) {}
9587

9688
/**
9789
* This function is invoked once when job is completed normally with the specified [value].
@@ -101,6 +93,7 @@ public abstract class AbstractCoroutine<in T>(
10193
/**
10294
* This function is invoked once when job is completed exceptionally with the specified [exception].
10395
*/
96+
// todo: rename to onCancelled
10497
protected open fun onCompletedExceptionally(exception: Throwable) {}
10598

10699
@Suppress("UNCHECKED_CAST")

common/kotlinx-coroutines-core-common/src/Builders.common.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ private open class StandaloneCoroutine(
210210
parentContext: CoroutineContext,
211211
active: Boolean
212212
) : AbstractCoroutine<Unit>(parentContext, active) {
213-
override val failsParent: Boolean get() = true
213+
override val cancelsParent: Boolean get() = true
214214
override fun handleJobException(exception: Throwable) = handleExceptionViaHandler(parentContext, exception)
215215
}
216216

common/kotlinx-coroutines-core-common/src/CompletableDeferred.kt

+6-4
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ package kotlinx.coroutines.experimental
77
import kotlinx.coroutines.experimental.selects.*
88

99
/**
10-
* A [Deferred] that can be completed via public functions
11-
* [complete], [completeExceptionally], and [cancel].
10+
* A [Deferred] that can be completed via public functions [complete] or [cancel][Job.cancel].
1211
*
13-
* Completion functions return `false` when this deferred value is already complete or completing.
12+
* Note, that [complete] functions returns `false` when this deferred value is already complete or completing,
13+
* while [cancel][Job.cancel] returns `true` as long the deferred is still _cancelling_ and the corresponding
14+
* exception is incorporated into the final [completion exception][getCompletionExceptionOrNull].
1415
*
1516
* An instance of completable deferred can be created by `CompletableDeferred()` function in _active_ state.
1617
*
@@ -32,6 +33,7 @@ public interface CompletableDeferred<T> : Deferred<T> {
3233
*
3334
* Repeated invocations of this function have no effect and always produce `false`.
3435
*/
36+
@Deprecated(message = "Use cancel", replaceWith = ReplaceWith("cancel(exception)"))
3537
public fun completeExceptionally(exception: Throwable): Boolean
3638
}
3739

@@ -61,7 +63,7 @@ private class CompletableDeferredImpl<T>(
6163
parent: Job?
6264
) : JobSupport(true), CompletableDeferred<T>, SelectClause1<T> {
6365
init { initParentJobInternal(parent) }
64-
override val onFailComplete get() = true
66+
override val onCancelComplete get() = true
6567
override fun getCompleted(): T = getCompletedInternal() as T
6668
override suspend fun await(): T = awaitInternal() as T
6769
override val onAwait: SelectClause1<T> get() = this

common/kotlinx-coroutines-core-common/src/CompletedExceptionally.kt

+2-10
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,20 @@ import kotlinx.coroutines.experimental.internal.*
88
import kotlin.coroutines.experimental.*
99

1010
/**
11-
* Class for an internal state of a job that had completed exceptionally, including cancellation.
11+
* Class for an internal state of a job that was cancelled (completed exceptionally).
1212
*
1313
* **Note: This class cannot be used outside of internal coroutines framework**.
1414
* **Note: cannot be internal and renamed until we get rid of MutableDelegateContinuation in IO**
1515
*
1616
* @suppress **This is unstable API and it is subject to change.**
1717
*/
18+
// todo: rename to Cancelled
1819
open class CompletedExceptionally(
1920
@JvmField public val cause: Throwable
2021
) {
2122
override fun toString(): String = "$classSimpleName[$cause]"
2223
}
2324

24-
/**
25-
* A specific subclass of [CompletedExceptionally] for cancelled jobs.
26-
*
27-
* **Note: This class cannot be used outside of internal coroutines framework**.
28-
*
29-
* @suppress **This is unstable API and it is subject to change.**
30-
*/
31-
internal class Cancelled(cause: Throwable) : CompletedExceptionally(cause)
32-
3325
/**
3426
* A specific subclass of [CompletedExceptionally] for cancelled [AbstractContinuation].
3527
*

common/kotlinx-coroutines-core-common/src/Deferred.kt

+9-7
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import kotlin.coroutines.experimental.*
1818
* successful or failed result of the computation that was carried out. The result of the deferred is
1919
* available when it is [completed][isCompleted] and can be retrieved by [await] method, which throws
2020
* exception if the deferred had failed.
21-
* A _failed_ deferred is considered to be [completed exceptionally][isCompletedExceptionally].
21+
* Note, that a _cancelled_ deferred is also considered to be completed.
2222
* The corresponding exception can be retrieved via [getCompletionExceptionOrNull] from a completed instance of deferred.
2323
*
2424
* Usually, a deferred value is created in _active_ state (it is created and started).
@@ -36,14 +36,17 @@ import kotlin.coroutines.experimental.*
3636
public interface Deferred<out T> : Job {
3737
/**
3838
* Returns `true` if computation of this deferred value has _completed exceptionally_.
39-
* It is `true` when both [isCompleted] and [isFailed] are true.
39+
* It is `true` when both [isCompleted] and [isCancelled] are true.
4040
* It implies that [isActive] is `false`.
41+
*
42+
* @suppress **Deprecated**: Use [isCancelled] && [isCompleted]
4143
*/
44+
@Deprecated("Use isCancelled && isCompleted", ReplaceWith("this.isCancelled && this.isCompleted"))
4245
public val isCompletedExceptionally: Boolean
4346

4447
/**
4548
* Awaits for completion of this value without blocking a thread and resumes when deferred computation is complete,
46-
* returning the resulting value or throwing the corresponding exception if the deferred had completed exceptionally or was cancelled.
49+
* returning the resulting value or throwing the corresponding exception if the deferred was cancelled.
4750
*
4851
* This suspending function is cancellable.
4952
* If the [Job] of the current coroutine is cancelled or completed while this suspending function is waiting, this function
@@ -63,17 +66,16 @@ public interface Deferred<out T> : Job {
6366

6467
/**
6568
* Returns *completed* result or throws [IllegalStateException] if this deferred value has not
66-
* [completed][isCompleted] yet. It throws the corresponding exception if this deferred has
67-
* [completed exceptionally][isCompletedExceptionally].
69+
* [completed][isCompleted] yet. It throws the corresponding exception if this deferred was [cancelled][isCancelled].
6870
*
6971
* This function is designed to be used from [invokeOnCompletion] handlers, when there is an absolute certainty that
7072
* the value is already complete. See also [getCompletionExceptionOrNull].
7173
*/
7274
public fun getCompleted(): T
7375

7476
/**
75-
* Returns *completion exception* result if this deferred [completed exceptionally][isCompletedExceptionally],
76-
* `null` if it is completed normally, or throws [IllegalStateException] if this deferred value has not
77+
* Returns *completion exception* result if this deferred was [cancelled][isCancelled] and has [completed][isCompleted],
78+
* `null` if it had completed normally, or throws [IllegalStateException] if this deferred value has not
7779
* [completed][isCompleted] yet.
7880
*
7981
* This function is designed to be used from [invokeOnCompletion] handlers, when there is an absolute certainty that

0 commit comments

Comments
 (0)