Skip to content

Commit e47cf26

Browse files
committed
fix: headers anchors
1 parent 55d92a3 commit e47cf26

File tree

1 file changed

+22
-22
lines changed

1 file changed

+22
-22
lines changed

docs/topics/coroutines-and-channels.md

+22-22
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ You can find this code in `src/contributors/Contributors.kt`.
168168
* The `loadContributors()` function is responsible for choosing how the contributors are loaded.
169169
* The `updateResults()` function updates the UI. As a result, it must always be called from the UI thread.
170170

171-
#### Task
171+
#### Task 8
172172

173173
To familiarize yourself with the task domain, complete the following task.
174174

@@ -191,7 +191,7 @@ After implementing this task, the resulting list for the "Kotlin" organization s
191191
>
192192
{type="note"}
193193

194-
#### Solution {initial-collapse-state="collapsed"}
194+
#### Solution 8 {initial-collapse-state="collapsed"}
195195

196196
Group users by their login. You can use
197197
[`groupBy()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/group-by.html) that returns a map from
@@ -211,7 +211,7 @@ An alternative is to use
211211
the [`groupingBy`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/grouping-by.html)function instead
212212
of `groupBy`.
213213

214-
## Using callbacks
214+
## Callbacks
215215

216216
The previous solution works, but blocks the thread and therefore freezes the UI. A traditional approach to avoiding this
217217
is to use callbacks.
@@ -264,12 +264,12 @@ the main UI thread(AWT event dispatching thread).
264264
However, if you try to load the contributors via the `BACKGROUND` option, you can see that the list is updated, but
265265
nothing changes.
266266

267-
#### Task
267+
#### Task 1
268268

269269
Fix the `loadContributorsBackground()` in `src/tasks/Request2Background.kt` so that the resulting list was shown in the
270270
UI.
271271

272-
#### Solution {initial-collapse-state="collapsed"}
272+
#### Solution 1 {initial-collapse-state="collapsed"}
273273

274274
Now the contributors are loaded, as you can see in the log, but the result isn't displayed. To fix this, call
275275
the `updateResults` on the resulting list of users:
@@ -334,11 +334,11 @@ option, you can see that nothing is shown. The tests that immediately return the
334334

335335
Think about why the given code doesn't work as expected and try to fix it or check the solution below.
336336

337-
#### Task (optional)
337+
#### Task 2 (optional)
338338

339339
Rewrite the code so that the loaded list of contributors is shown.
340340

341-
#### Solution (first attempt) {initial-collapse-state="collapsed"}
341+
#### Solution 2 (first attempt) {initial-collapse-state="collapsed"}
342342

343343
Now many requests are started concurrently, which decreases the total loading time. However, the result isn't loaded.
344344
The `updateResults` callback is called right after all the loading requests are started, so the `allUsers` list is not
@@ -366,7 +366,7 @@ for ((index, repo) in repos.withIndex()) { // #1
366366

367367
However, this code is also incorrect. Try to find an answer yourself or check the solution below.
368368

369-
#### Solution (second attempt) {initial-collapse-state="collapsed"}
369+
#### Solution 2 (second attempt) {initial-collapse-state="collapsed"}
370370

371371
Since the loading requests are started concurrently, no one guarantees that the result for the last one comes last. The
372372
results can come in any order.
@@ -399,7 +399,7 @@ for (repo in repos) {
399399
>
400400
type={"note"}
401401

402-
#### Solution (third attempt) {initial-collapse-state="collapsed"}
402+
#### Solution 2 (third attempt) {initial-collapse-state="collapsed"}
403403

404404
An even better solution is to use the `CountDownLatch` class. It stores a counter initialized with the number of
405405
repositories. This counter is decremented after processing each repository. It then waits until the latch is counted
@@ -468,7 +468,7 @@ interface GitHubService {
468468
}
469469
```
470470

471-
#### Task
471+
#### Task 3
472472

473473
The task is to change the code of the function loading contributors to make use of the new suspending functions.
474474

@@ -482,7 +482,7 @@ Modify so that the new suspending functions are used instead of ones returning `
482482
Run the program by choosing the `SUSPEND` option and ensure that the UI is still responsive while the GitHub requests
483483
are performed.
484484

485-
#### Solution {initial-collapse-state="collapsed"}
485+
#### Solution 3 {initial-collapse-state="collapsed"}
486486

487487
Replace `.getOrgReposCall(req.org).execute()` with `.getOrgRepos(req.org)` and repeat the same replacement for the
488488
second "contributors" request:
@@ -667,12 +667,12 @@ can be sent before the result for the previous one is received:
667667
The total loading time is approximately the same as in the `CALLBACKS` version, but it doesn't need any callbacks.
668668
What's more, `async` explicitly emphasizes which parts run concurrently in the code.
669669

670-
#### Task
670+
#### Task 4
671671

672672
In the `Request5Concurrent.kt` file, implement a `loadContributorsConcurrent()` function. For that, use the
673673
previous `loadContributorsSuspend()` function.
674674

675-
#### Tip {initial-collapse-state="collapsed"}
675+
#### Tip 4 {initial-collapse-state="collapsed"}
676676

677677
As you'll see later, you can only start a new coroutine inside a coroutine scope. Copy the content
678678
from `loadContributorsSuspend()` to the `coroutineScope` call, so that you can call `async` functions there:
@@ -696,7 +696,7 @@ val deferreds: List<Deferred<List<User>>> = repos.map { repo ->
696696
deferreds.awaitAll() // List<List<User>>
697697
```
698698

699-
#### Solution {initial-collapse-state="collapsed"}
699+
#### Solution 4 {initial-collapse-state="collapsed"}
700700

701701
Wrap each "contributors" request with `async` to create as many coroutines as the number of repositories. `async`
702702
returns `Deferred<List<User>>`.
@@ -1086,7 +1086,7 @@ call `withContext`, which is a `suspend` function inside the corresponding lambd
10861086
`updateResults` callback takes an additional Boolean parameter as an argument saying whether all the loading completed
10871087
and the results are final.
10881088

1089-
#### Task
1089+
#### Task 5
10901090

10911091
In the `Request6Progress.kt` file, implement the `loadContributorsProgress()` function that shows the intermediate
10921092
progress. Base it on the `loadContributorsSuspend` function from `Request4Suspend.kt`.
@@ -1099,7 +1099,7 @@ Use a simple version without concurrency; you'll add it later in the next sectio
10991099
>
11001100
{type="note"}
11011101

1102-
#### Solution {initial-collapse-state="collapsed"}
1102+
#### Solution 5 {initial-collapse-state="collapsed"}
11031103

11041104
To store the intermediate list of loaded contributors in the "aggregated" state, define an `allUsers` variable which
11051105
stores the list of users, and then update it after contributors for each new repository are loaded:
@@ -1278,15 +1278,15 @@ To get a better understanding, watch the following video:
12781278

12791279
![Video explaining the channels sample](https://youtu.be/HpWQUoVURWQ)
12801280

1281-
#### Task
1281+
#### Task 6
12821282

12831283
Implement the function `loadContributorsChannels()` that requests all the GitHub contributors concurrently but shows
12841284
intermediate progress at the same time.
12851285

12861286
For this, use previous functions, `loadContributorsConcurrent()` from `Request5Concurrent.kt`
12871287
and `loadContributorsProgress()` from `Request6Progress.kt`.
12881288

1289-
#### Tip {initial-collapse-state="collapsed"}
1289+
#### Tip 6 {initial-collapse-state="collapsed"}
12901290

12911291
Different coroutines that concurrently receive contributor lists for different repositories can send all the received
12921292
results to the same channel:
@@ -1313,7 +1313,7 @@ repeat(repos.size) {
13131313

13141314
Since the `receive()` calls are sequential, no additional synchronization is needed.
13151315

1316-
#### Solution {initial-collapse-state="collapsed"}
1316+
#### Solution 6 {initial-collapse-state="collapsed"}
13171317

13181318
As with the `loadContributorsProgress()` function, you can create an `allUsers` variable to store the intermediate
13191319
states of the "all contributors" list.
@@ -1504,7 +1504,7 @@ compileTestKotlin {
15041504

15051505
In the project corresponding to this tutorial it's already been added to the Gradle script.
15061506

1507-
#### Task
1507+
#### Task 7
15081508

15091509
Refactor all the following tests in `tests/tasks/` to use virtual time instead of real-time:
15101510

@@ -1517,7 +1517,7 @@ Request7ChannelsKtTest.kt
15171517

15181518
Compare the total running time with the time before this refactoring.
15191519

1520-
#### Tip {initial-collapse-state="collapsed"}
1520+
#### Tip 7 {initial-collapse-state="collapsed"}
15211521

15221522
Replace `runBlocking` invocation with `runBlockingTest`, and
15231523
`System.currentTimeMillis()` with `currentTime`:
@@ -1535,7 +1535,7 @@ fun test() = runBlockingTest {
15351535
Uncomment the assertions checking the exact virtual time.
15361536
Don't forget to add `@UseExperimental(ExperimentalCoroutinesApi::class)`.
15371537

1538-
#### Solution {initial-collapse-state="collapsed"}
1538+
#### Solution 7 {initial-collapse-state="collapsed"}
15391539

15401540
Here's the solution for the concurrent case:
15411541

0 commit comments

Comments
 (0)