Skip to content

Commit

Permalink
Fix more typos; reword some phrases; add "job:" to textual output in … (
Browse files Browse the repository at this point in the history
Kotlin#1154)

* Fix more typos; reword some phrases; add "job:" to textual output in examples
to better differentiate between the "main" and "job" coroutines
* Gradle knit
  • Loading branch information
Inego authored and elizarov committed May 6, 2019
1 parent d0f6229 commit 563b7e5
Show file tree
Hide file tree
Showing 16 changed files with 135 additions and 136 deletions.
2 changes: 1 addition & 1 deletion coroutines-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ The main coroutines guide has moved to the [docs folder](docs/coroutines-guide.m
* <a name='cancelling-coroutine-execution'></a>[Cancelling coroutine execution](docs/cancellation-and-timeouts.md#cancelling-coroutine-execution)
* <a name='cancellation-is-cooperative'></a>[Cancellation is cooperative](docs/cancellation-and-timeouts.md#cancellation-is-cooperative)
* <a name='making-computation-code-cancellable'></a>[Making computation code cancellable](docs/cancellation-and-timeouts.md#making-computation-code-cancellable)
* <a name='closing-resources-with-finally'></a>[Closing resources with finally](docs/cancellation-and-timeouts.md#closing-resources-with-finally)
* <a name='closing-resources-with-`finally`'></a>[Closing resources with `finally`](docs/cancellation-and-timeouts.md#closing-resources-with-`finally`)
* <a name='run-non-cancellable-block'></a>[Run non-cancellable block](docs/cancellation-and-timeouts.md#run-non-cancellable-block)
* <a name='timeout'></a>[Timeout](docs/cancellation-and-timeouts.md#timeout)
<!--- TOC_REF docs/composing-suspending-functions.md -->
Expand Down
82 changes: 41 additions & 41 deletions docs/cancellation-and-timeouts.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class CancellationTimeOutsGuideTest {
* [Cancelling coroutine execution](#cancelling-coroutine-execution)
* [Cancellation is cooperative](#cancellation-is-cooperative)
* [Making computation code cancellable](#making-computation-code-cancellable)
* [Closing resources with finally](#closing-resources-with-finally)
* [Closing resources with `finally`](#closing-resources-with-`finally`)
* [Run non-cancellable block](#run-non-cancellable-block)
* [Timeout](#timeout)

Expand All @@ -49,7 +49,7 @@ fun main() = runBlocking {
//sampleStart
val job = launch {
repeat(1000) { i ->
println("I'm sleeping $i ...")
println("job: I'm sleeping $i ...")
delay(500L)
}
}
Expand All @@ -69,9 +69,9 @@ fun main() = runBlocking {
It produces the following output:

```text
I'm sleeping 0 ...
I'm sleeping 1 ...
I'm sleeping 2 ...
job: I'm sleeping 0 ...
job: I'm sleeping 1 ...
job: I'm sleeping 2 ...
main: I'm tired of waiting!
main: Now I can quit.
```
Expand Down Expand Up @@ -104,7 +104,7 @@ fun main() = runBlocking {
while (i < 5) { // computation loop, just wastes CPU
// print a message twice a second
if (System.currentTimeMillis() >= nextPrintTime) {
println("I'm sleeping ${i++} ...")
println("job: I'm sleeping ${i++} ...")
nextPrintTime += 500L
}
}
Expand All @@ -125,12 +125,12 @@ Run it to see that it continues to print "I'm sleeping" even after cancellation
until the job completes by itself after five iterations.

<!--- TEST
I'm sleeping 0 ...
I'm sleeping 1 ...
I'm sleeping 2 ...
job: I'm sleeping 0 ...
job: I'm sleeping 1 ...
job: I'm sleeping 2 ...
main: I'm tired of waiting!
I'm sleeping 3 ...
I'm sleeping 4 ...
job: I'm sleeping 3 ...
job: I'm sleeping 4 ...
main: Now I can quit.
-->

Expand All @@ -156,7 +156,7 @@ fun main() = runBlocking {
while (isActive) { // cancellable computation loop
// print a message twice a second
if (System.currentTimeMillis() >= nextPrintTime) {
println("I'm sleeping ${i++} ...")
println("job: I'm sleeping ${i++} ...")
nextPrintTime += 500L
}
}
Expand All @@ -173,22 +173,22 @@ fun main() = runBlocking {

> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-cancel-03.kt).
As you can see, now this loop is cancelled. [isActive] is an extension property that is
available inside the code of coroutine via [CoroutineScope] object.
As you can see, now this loop is cancelled. [isActive] is an extension property
available inside the coroutine via the [CoroutineScope] object.

<!--- TEST
I'm sleeping 0 ...
I'm sleeping 1 ...
I'm sleeping 2 ...
job: I'm sleeping 0 ...
job: I'm sleeping 1 ...
job: I'm sleeping 2 ...
main: I'm tired of waiting!
main: Now I can quit.
-->

### Closing resources with finally
### Closing resources with `finally`

Cancellable suspending functions throw [CancellationException] on cancellation which can be handled in
a usual way. For example, `try {...} finally {...}` expression and Kotlin `use` function execute their
finalization actions normally when coroutine is cancelled:
the usual way. For example, `try {...} finally {...}` expression and Kotlin `use` function execute their
finalization actions normally when a coroutine is cancelled:


<div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
Expand All @@ -201,11 +201,11 @@ fun main() = runBlocking {
val job = launch {
try {
repeat(1000) { i ->
println("I'm sleeping $i ...")
println("job: I'm sleeping $i ...")
delay(500L)
}
} finally {
println("I'm running finally")
println("job: I'm running finally")
}
}
delay(1300L) // delay a bit
Expand All @@ -220,15 +220,15 @@ fun main() = runBlocking {

> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-cancel-04.kt).
Both [join][Job.join] and [cancelAndJoin] wait for all the finalization actions to complete,
Both [join][Job.join] and [cancelAndJoin] wait for all finalization actions to complete,
so the example above produces the following output:

```text
I'm sleeping 0 ...
I'm sleeping 1 ...
I'm sleeping 2 ...
job: I'm sleeping 0 ...
job: I'm sleeping 1 ...
job: I'm sleeping 2 ...
main: I'm tired of waiting!
I'm running finally
job: I'm running finally
main: Now I can quit.
```

Expand All @@ -240,7 +240,7 @@ Any attempt to use a suspending function in the `finally` block of the previous
[CancellationException], because the coroutine running this code is cancelled. Usually, this is not a
problem, since all well-behaving closing operations (closing a file, cancelling a job, or closing any kind of a
communication channel) are usually non-blocking and do not involve any suspending functions. However, in the
rare case when you need to suspend in the cancelled coroutine you can wrap the corresponding code in
rare case when you need to suspend in a cancelled coroutine you can wrap the corresponding code in
`withContext(NonCancellable) {...}` using [withContext] function and [NonCancellable] context as the following example shows:

<div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
Expand All @@ -253,14 +253,14 @@ fun main() = runBlocking {
val job = launch {
try {
repeat(1000) { i ->
println("I'm sleeping $i ...")
println("job: I'm sleeping $i ...")
delay(500L)
}
} finally {
withContext(NonCancellable) {
println("I'm running finally")
println("job: I'm running finally")
delay(1000L)
println("And I've just delayed for 1 sec because I'm non-cancellable")
println("job: And I've just delayed for 1 sec because I'm non-cancellable")
}
}
}
Expand All @@ -277,18 +277,18 @@ fun main() = runBlocking {
> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-cancel-05.kt).
<!--- TEST
I'm sleeping 0 ...
I'm sleeping 1 ...
I'm sleeping 2 ...
job: I'm sleeping 0 ...
job: I'm sleeping 1 ...
job: I'm sleeping 2 ...
main: I'm tired of waiting!
I'm running finally
And I've just delayed for 1 sec because I'm non-cancellable
job: I'm running finally
job: And I've just delayed for 1 sec because I'm non-cancellable
main: Now I can quit.
-->

### Timeout

The most obvious reason to cancel coroutine execution in practice
The most obvious practical reason to cancel execution of a coroutine
is because its execution time has exceeded some timeout.
While you can manually track the reference to the corresponding [Job] and launch a separate coroutine to cancel
the tracked one after delay, there is a ready to use [withTimeout] function that does it.
Expand Down Expand Up @@ -331,10 +331,10 @@ We have not seen its stack trace printed on the console before. That is because
inside a cancelled coroutine `CancellationException` is considered to be a normal reason for coroutine completion.
However, in this example we have used `withTimeout` right inside the `main` function.

Because cancellation is just an exception, all the resources are closed in a usual way.
You can wrap the code with timeout in `try {...} catch (e: TimeoutCancellationException) {...}` block if
you need to do some additional action specifically on any kind of timeout or use [withTimeoutOrNull] function
that is similar to [withTimeout], but returns `null` on timeout instead of throwing an exception:
Since cancellation is just an exception, all resources are closed in the usual way.
You can wrap the code with timeout in a `try {...} catch (e: TimeoutCancellationException) {...}` block if
you need to do some additional action specifically on any kind of timeout or use the [withTimeoutOrNull] function
that is similar to [withTimeout] but returns `null` on timeout instead of throwing an exception:

<div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">

Expand Down
4 changes: 2 additions & 2 deletions kotlinx-coroutines-core/common/src/Annotations.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public annotation class ExperimentalCoroutinesApi
* Its API and semantics can and will be changed in next releases.
*
* Feature preview can be used to evaluate its real-world strengths and weaknesses, gather and provide feedback.
* According to the feedback, [Flow] will be refined on its road to stabilization and promotion to stable API.
* According to the feedback, [Flow] will be refined on its road to stabilization and promotion to a stable API.
*/
@MustBeDocumented
@Retention(value = AnnotationRetention.BINARY)
Expand All @@ -44,7 +44,7 @@ public annotation class ObsoleteCoroutinesApi

/**
* Marks declarations that are **internal** in coroutines API, which means that should not be used outside of
* `kotlinx.coroutines`, because their signatures and semantics will be changing between release without any
* `kotlinx.coroutines`, because their signatures and semantics will change between future releases without any
* warnings and without providing any migration aids.
*/
@Retention(value = AnnotationRetention.BINARY)
Expand Down
4 changes: 2 additions & 2 deletions kotlinx-coroutines-core/common/src/CoroutineScope.kt
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public interface CoroutineScope {
/**
* The context of this scope.
* Context is encapsulated by the scope and used for implementation of coroutine builders that are extensions on the scope.
* Accessing this property in general code is not recommended for any purposes except accessing [Job] instance for advanced usages.
* Accessing this property in general code is not recommended for any purposes except accessing the [Job] instance for advanced usages.
*
* By convention, should contain an instance of a [job][Job] to enforce structured concurrency.
*/
Expand Down Expand Up @@ -91,7 +91,7 @@ public operator fun CoroutineScope.plus(context: CoroutineContext): CoroutineSco
public fun MainScope(): CoroutineScope = ContextScope(SupervisorJob() + Dispatchers.Main)

/**
* Returns `true` when current [Job] is still active (has not completed and was not cancelled yet).
* Returns `true` when the current [Job] is still active (has not completed and was not cancelled yet).
*
* Check this property in long-running computation loops to support cancellation:
* ```
Expand Down
30 changes: 15 additions & 15 deletions kotlinx-coroutines-core/common/src/Dispatchers.common.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,36 +13,36 @@ public expect object Dispatchers {
/**
* The default [CoroutineDispatcher] that is used by all standard builders like
* [launch][CoroutineScope.launch], [async][CoroutineScope.async], etc
* if no dispatcher nor any other [ContinuationInterceptor] is specified in their context.
* if neither a dispatcher nor any other [ContinuationInterceptor] is specified in their context.
*
* It is backed by a shared pool of threads on JVM. By default, the maximal number of threads used
* by this dispatcher is equal to the number CPU cores, but is at least two.
* It is backed by a shared pool of threads on JVM. By default, the maximum number of threads used
* by this dispatcher is equal to the number of CPU cores, but is at least two.
*/
public val Default: CoroutineDispatcher

/**
* A coroutine dispatcher that is confined to the Main thread operating with UI objects.
* Usually such dispatcher is single-threaded.
* Usually such dispatchers are single-threaded.
*
* Access to this property may throw [IllegalStateException] if no main dispatchers are present in the classpath.
* Access to this property may throw an [IllegalStateException] if no main dispatchers are present in the classpath.
*
* Depending on platform and classpath it can be mapped to different dispatchers:
* - On JS and Native it is equivalent of [Default] dispatcher.
* - On JVM it either Android main thread dispatcher, JavaFx or Swing EDT dispatcher. It is chosen by
* - On JS and Native it is equivalent to the [Default] dispatcher.
* - On JVM it either the Android main thread dispatcher, JavaFx or Swing EDT dispatcher. It is chosen by the
* [`ServiceLoader`](https://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html).
*
* In order to work with `Main` dispatcher, following artifact should be added to project runtime dependencies:
* - `kotlinx-coroutines-android` for Android Main thread dispatcher
* - `kotlinx-coroutines-javafx` for JavaFx Application thread dispatcher
* - `kotlinx-coroutines-swing` for Swing EDT dispatcher
* In order to work with the `Main` dispatcher, the following artifact should be added to the project runtime dependencies:
* - `kotlinx-coroutines-android` &mdash; for Android Main thread dispatcher
* - `kotlinx-coroutines-javafx` &mdash; for JavaFx Application thread dispatcher
* - `kotlinx-coroutines-swing` &mdash; for Swing EDT dispatcher
*
* Implementation note: [MainCoroutineDispatcher.immediate] is not supported on Native and JS platforms.
* Implementation note: [MainCoroutineDispatcher.immediate] is not supported on the Native and JS platforms.
*/
public val Main: MainCoroutineDispatcher

/**
* A coroutine dispatcher that is not confined to any specific thread.
* It executes initial continuation of the coroutine in the current call-frame
* It executes the initial continuation of a coroutine in the current call-frame
* and lets the coroutine resume in whatever thread that is used by the corresponding suspending function, without
* mandating any specific threading policy. Nested coroutines launched in this dispatcher form an event-loop to avoid
* stack overflows.
Expand All @@ -64,12 +64,12 @@ public expect object Dispatchers {
* println("Done")
* ```
* Can print both "1 2 3" and "1 3 2", this is an implementation detail that can be changed.
* But it is guaranteed that "Done" will be printed only when both `withContext` are completed.
* But it is guaranteed that "Done" will be printed only when both `withContext` calls are completed.
*
* Note that if you need your coroutine to be confined to a particular thread or a thread-pool after resumption,
* but still want to execute it in the current call-frame until its first suspension, then you can use
* an optional [CoroutineStart] parameter in coroutine builders like
* [launch][CoroutineScope.launch] and [async][CoroutineScope.async] setting it to the
* [launch][CoroutineScope.launch] and [async][CoroutineScope.async] setting it to
* the value of [CoroutineStart.UNDISPATCHED].
*/
public val Unconfined: CoroutineDispatcher
Expand Down
30 changes: 15 additions & 15 deletions kotlinx-coroutines-core/common/src/Timeout.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ import kotlin.coroutines.intrinsics.*
import kotlin.jvm.*

/**
* Runs a given suspending [block] of code inside a coroutine with a specified timeout and throws
* [TimeoutCancellationException] if timeout was exceeded.
* Runs a given suspending [block] of code inside a coroutine with a specified [timeout][timeMillis] and throws
* a [TimeoutCancellationException] if the timeout was exceeded.
*
* The code that is executing inside the [block] is cancelled on timeout and the active or next invocation of
* cancellable suspending function inside the block throws [TimeoutCancellationException].
* the cancellable suspending function inside the block throws a [TimeoutCancellationException].
*
* The sibling function that does not throw exception on timeout is [withTimeoutOrNull].
* Note that timeout action can be specified for [select] invocation with [onTimeout][SelectBuilder.onTimeout] clause.
* The sibling function that does not throw an exception on timeout is [withTimeoutOrNull].
* Note that the timeout action can be specified for a [select] invocation with [onTimeout][SelectBuilder.onTimeout] clause.
*
* Implementation note: how exactly time is tracked is an implementation detail of [CoroutineDispatcher] in the context.
* Implementation note: how the time is tracked exactly is an implementation detail of the context's [CoroutineDispatcher].
*
* @param timeMillis timeout time in milliseconds.
*/
Expand All @@ -33,16 +33,16 @@ public suspend fun <T> withTimeout(timeMillis: Long, block: suspend CoroutineSco
}

/**
* Runs a given suspending block of code inside a coroutine with a specified timeout and returns
* Runs a given suspending block of code inside a coroutine with a specified [timeout][timeMillis] and returns
* `null` if this timeout was exceeded.
*
* The code that is executing inside the [block] is cancelled on timeout and the active or next invocation of
* cancellable suspending function inside the block throws [TimeoutCancellationException].
* cancellable suspending function inside the block throws a [TimeoutCancellationException].
*
* The sibling function that throws exception on timeout is [withTimeout].
* Note that timeout action can be specified for [select] invocation with [onTimeout][SelectBuilder.onTimeout] clause.
* The sibling function that throws an exception on timeout is [withTimeout].
* Note that the timeout action can be specified for a [select] invocation with [onTimeout][SelectBuilder.onTimeout] clause.
*
* Implementation note: how exactly time is tracked is an implementation detail of [CoroutineDispatcher] in the context.
* Implementation note: how the time is tracked exactly is an implementation detail of the context's [CoroutineDispatcher].
*
* @param timeMillis timeout time in milliseconds.
*/
Expand All @@ -57,7 +57,7 @@ public suspend fun <T> withTimeoutOrNull(timeMillis: Long, block: suspend Corout
setupTimeout<T?, T?>(timeoutCoroutine, block)
}
} catch (e: TimeoutCancellationException) {
// Return null iff it's our exception, otherwise propagate it upstream (e.g. in case of nested withTimeouts)
// Return null if it's our exception, otherwise propagate it upstream (e.g. in case of nested withTimeouts)
if (e.coroutine === coroutine) {
return null
}
Expand All @@ -73,8 +73,8 @@ private fun <U, T: U> setupTimeout(
val cont = coroutine.uCont
val context = cont.context
coroutine.disposeOnCompletion(context.delay.invokeOnTimeout(coroutine.time, coroutine))
// restart block using new coroutine with new job,
// however start it as undispatched coroutine, because we are already in the proper context
// restart the block using a new coroutine with a new job,
// however, start it undispatched, because we already are in the proper context
return coroutine.startUndispatchedOrReturnIgnoreTimeout(coroutine, block)
}

Expand Down Expand Up @@ -114,7 +114,7 @@ public class TimeoutCancellationException internal constructor(
@JvmField internal val coroutine: Job?
) : CancellationException(message) {
/**
* Creates timeout exception with a given message.
* Creates a timeout exception with the given message.
* This constructor is needed for exception stack-traces recovery.
*/
@Suppress("UNUSED")
Expand Down
Loading

0 comments on commit 563b7e5

Please sign in to comment.