Kotlinの新しい非同期処理 - QCon SFでのRoman Elizarov氏の講演より
- 共有
-
- |
後で読む
マイリーディングリスト
JetBrainsでKotlinライブラリの開発リーダを務めるRoman Elizarov氏がQCon Sun Franciscoで、“Fresh Async with Kotlin”と題した講演を行なった。講演の中で氏は、JavaやC#、JavaScriptなどの言語で非同期コードを記述することの難しさと、Kotlinがいかに対処しているかを実演してみせた。Kotlinで書かれた非同期コードは、Javaなどの言語で多くの開発者が書き慣れている通常の同期コードとほとんど変わらない。
従来のアプリケーションは直接的な計算や処理が中心だったが、新しいアプリケーションでは、多くがREST APIやマイクロサービスといったサービスの呼び出しを行なっている。このアーキテクチャスタイルでは、結果が戻ってくるのを待つのが一般的だ。
上記のコードはrequestToken()
サービスをコールしてtoken
を待ち、取得したトークンをcreatePost()
サービスに渡して生成されるpost
を待った上で、最後にprocessPost()
サービスをコールしてpost
を表示する。
この処理を実装する簡単な方法のひとつはスレッドを使うことだ。しかしながら、上の3ステップのような単純なケースならば問題にはならないが、多数のサービスコールが関わる複雑なアプリケーションでは、スレッドに大きく依存する方法が機能しない場合がある。各スレッドがメモリとスケジューリングのオーバヘッドを持つため、最新鋭のマシンでさえ、一度に起動できるスレッドの数には制限があるからだ。
特にJavaScriptを使用したシングルスレッド環境において、スレッドの代替となるのがコールバックだ。しかしコードバックを使用したコードは、以下の例に示すような、“コールバック地獄(callback hell)”と呼ばれる過剰なネストを起こしやすい。
このようなコードのネストの問題は、複雑なコードではさらに悪化する — コールバックでネストしたコードは本質的に読み難く、デバッグが難しいのだ。
近年では、コールバック地獄の問題に対処する優れた代用策として、Future/Promise/Rxが知られるようになった。これらはすべて、同じアイデアを異なる言語で実装したものだ。
Future/Promiseを使用して記述されたコードは、コールバック地獄よりも読みやすく、理解も容易だ。このアプローチには例外処理機構も組み込まれているため、コードのデバッグも簡単になる。
しかしながら、Future/Promiesを使った場合にも、以前として潜在的な問題がある。例えば、Futureコンテナオブジェクトで複数のコンビネータメソッドを処理する場合だ。先程のコードでは、.thenCompose
と.thenAccept
という2つのコンビネータを使用する。コンビネータは他の言語では違う名称を持つ場合もある。また、開発者は、コードブランチやループのためのコンビネータも意識しなくてならない。
Kotlinのコルーチンは、開発者がFuture/Promiseで直面する問題の緩和を目標とする。コルーチンでは、同期コードの記述で使用するような、自然なシグネチャでコードを書くことができる。コルーチン定義の先頭では、非同期オペレーションを示すためにsuspend
というキーワードを使用する。
このアプローチの欠点は、どのサービス呼び出しが非同期なのかを知るのが難しいことだ。例えば上記のコードでは、requestToken()
とcreatePost()
コールが非同期であることを指定する方法がない。この問題にはIDEが、ガター内のサスペンドポイントマーカを示すことで貢献してくれる。
コルーチンを使うことで、一般的なループや例外処理、forEach
やlet
、apply
、repeat
、filter
、map
、use
などの一般的な高次関数を記述できるようになった。独自の高次関数も、同期コーディングで使用される通常のコーディングスタイルで作成可能だ。
内部的には、suspend
キーワードが指定されていると、KotlinコンパイラがJVMバイトコードのレベルで、関数呼び出しに暗黙のContinuationパラメータを追加する。このContinuationパラメータは、基本的にはコールバックである。
コード内にサスペンドポイントが見つかると、Kotlinはそれをステートマシンにコンパイルして、サスペンドをそのステートマシンに保存する。
非同期プログラミングをサポートする目的でKotlinに用意されているすべてのコルーチンを知るには、Kotlinのコルーチンライブラリを調べるとよいだろう。これらライブラリは現在も開発中であるため、現時点では試験的(experimental)とされているが、この中にはCompleteableFuture、RxJava、Reactive Streamsといった他の非同期プログラミングアプローチとの統合や、AndroidやJavaFXといったシングルスレッドUIフレームワークとKotlinとの統合を実現するフックも含まれている。
- IntelliJ IDEA 2017.3リリース 2017年12月25日
- MicroProfile 1.2の最新情報 2017年12月20日
- サーブレット対リアクティブ: 正しいスタックを選定する - Rossen Stoyanchev氏のQCon SF 2017でのプレゼンテーション 2017年12月12日
- Javaのバリュータイプに対する設計が進んでいる 2017年12月12日
- Kotlin 1.2がマルチプラットフォームプロジェクトを導入 2017年12月12日
- SpringOne 2017 Platform Conference - 1日目 2017年12月12日
- オラクルがEclipse MicroProfileプロジェクトへ加入 2017年12月7日
- Spring Tool Suite 3.9.1 リリース 2017年11月30日
- Java 10 - これまでの経緯 2017年11月30日
- AndroidアプリでのKotlin利用が増加中、Googleもサポート 2017年11月30日
- OracleがオープンソースのFn Projectを公開、サーバレス競争に参戦 2017年11月28日
- OracleがJDKの全ての機能をオープンソース化し、Java EEの欠点に取り組む計画を発表した 2017年11月27日
- ZGC - オラクルの巨大ヒープ向けガベージコレクタ 2017年11月24日
- Eclipse MicroProfileでJavaでのマイクロサービスの採用を加速させる 2017年11月16日
- EE4J、EclipseファウンデーションがオープンソースJava EEを準備 2017年11月16日
こんにちは
コメントするには InfoQアカウントの登録 または ログイン が必要です。InfoQ に登録するとさまざまなことができます。アカウント登録をしてInfoQをお楽しみください。
あなたの意見をお聞かせください。