今週は第57回を開催しました!
引き続きKotlin Hands-onをすすめています。
前回の様子はコチラ↓
[第57回の様子]
2021/3/24に第56回を開催した。
参加メンバーは自分をいれて3名。今回は久しぶりのメンバーも参加してくれた!
今回、自分はナビゲータ役で参加した。
勉強会本編の内容としては、ひき続きIntroduction to Coroutines and Channelsハンズオンを進めた。第6章 Structured Concurrencyを半分ほど進めた。
[学んだことや疑問点]
- Introduction to Coroutines and Channels: 6. Structured Concurrency
- Coroutine scopeの役割は異なるCoroutine間の親子関係を持たせること
- Coroutine contextにはcoroutineの名前やどのスレッドでcoroutineを実行すべきかといった追加の技術情報が含まれている
launchやasyncによって、新しいcoroutineは常にcoroutine scopeの中でのみ開始できる:runBlockingのみ例外的なトップレベル関数として定義されているlaunchやasyncはCoroutineScopeの拡張関数なのでcoroutine scopeの中でのみ呼び出せる
import kotlinx.coroutines.*
fun main() = runBlocking { /* ここでのthisはCoroutineScope */
launch { /* これはrunBlockingで開始されたCoroutineScopeの子供のスコープ */ }
// 上の行は以下の行と同じ意味
this.launch { /* ... */ }
}
coroutineScope()関数を使うとcoroutineを開始することなくCoroutineScopeを作成できるsuspend関数のなかで新しいcoroutineを使う場合にcoroutineScope()関数を利用した(前回・前々回のloadContributorsConcurrent関数がそれ:suspend関数はcoroutine scopeの中で呼ばれるので、そのスコープの子供のスコープが作成される)GlobalScope.async()やGlobalScope.launch()で親子関係のない独立したcoroutine scopeを開始することもできる:独立しているので明示的にcoroutineへの参照を保持してキャンセルする必要がある- Coroutine Scopeに親子関係があることで以下の利点がある
- 親スコープが子のスコープを管理する、子の寿命は親の寿命に制限される
- 親スコープがキャンセルされると、子のcoroutineもキャンセルされる
- 親coroutineは子のcoroutineの完了を待つ
- ローディング処理をキャンセルする
- 前回実装した
loadContributorsConcurrentをキャンセルしやすくするために、delay処理を追加する
suspend fun loadContributorsConcurrent(service: GitHubService, req: RequestData): List<User> = coroutineScope {
// ...
async {
log("starting loading for ${repo.name}")
delay(3000)
// load repo contributors
}
// ...
result
}
suspend fun loadContributorsConcurrent(service: GitHubService, req: RequestData): List<User> = {
// ...
GlobalScope.async {
log("starting loading for ${repo.name}")
delay(3000)
// load repo contributors
}
// ...
result
}
- 動作確認をするぞ!というところで時間ぎれ....続きは次週!
[まとめ]
モブプログラミング・スタイルで、Introduction to Coroutines and Channelsハンズオンを進めた。
Coroutineのcontextとscopeの違い、scopeの親子関係とGlobalScopeなど、Structured Concurrencyについて理解を深められた!!
今週のプルリクエストはこちら。