2015/2/18
アリエル・ネットワーク 池添
 非同期処理の重要性
 C10K問題
 Node.jsでは、I/Oに関するAPIはすべて非同期
 UX
 スマホでは、しばらく応答のないアプリは強制終了
 WinRT APIでは、50msec以上かかりそうな処理はすべて非同期
 非同期処理を扱う機会が増えている。
 非同期処理をきれいに書くためにPromiseやReactiveに注目が集まっている。
 最近、いろんな人たちがいろんな意味でリアク
ティブという言葉を使っている。
 それぞれ若干意味が異なっている。
 バズワード化
FRP
Reactive
Manifesto
React.js
Rx Google Trends
 時間や外部の入力と共に変化する値を、
反応的(reactive)に処理するプログラミ
ングパラダイム。
 アニメーション、GUIプログラミング、セ
ンサやロボット制御プログラムなどを実
現するときに役立つ。
 2種類の入力の概念を扱う
 Behavior
 時間に伴い連続的に変化する値
 Signal
 時間順に並ぶ離散的なイベント
var a = 1
var b = a + 1
a = 10 // aを書き換える
print b // => 11
時間[t]
 よくある例
 イベントストリームの例
xs:[e1, e2, e3,e4, e5]
非同期に発生するイベントを
無限リストのように扱う
 Reactive Programmingを関数型プログラミング言語で実現したもの。
let
result :: Behavior t (Maybe Int)
result = f <$> input1 <*> input2
where
f x y = liftA2 (+) (readNumber x) (readNumber y)
 Microsoft ResearchでErik Meijer(Haskell仕様策定者の一人)が中心となって開発。
 FRPを実用レベルに落とし込んだ。
 C#実装
 Signalのみに特化
 エラーハンドリング
 リソース管理
 スケジューラ
 テストのための機能
 Hot Observable, Cold Observable
 豊富な関数群
 Rxを好むプログラマーが多く、他のプログラミ
ング言語への移植が進んでいる。
 Rx開発者の1人がNetflix社に移り、RxJavaを
開発。Rxの普及に大きな貢献。
 Rx実装を取りまとめたReactiveXというコミュ
ニティも誕生。
 Microsoft
 Rx (C#)
 RxJS
 RxCpp
 RxPy
 Rx.ObjC
 ReactiveX
 RxJava
 RxRust
 Rx.rb
 RxScala
 RxAndroid
 RxKotlin
 RxGroovy
 RxGo
 RxClojure
 そのほか
 ReactiveCocoa
 BaconJS
 Scalaを開発しているTypesafe社が提唱
 下記の特徴を持ったアーキテクチャを
リアクティブシステムと呼ぶ。
 即応性
 耐障害性
 弾力性
 メッセージ駆動
 リアクティブシステムを構築するためにAkkaの利用を推奨している。
 Akkaのマーケティングとしてリアクティブという言葉に便乗したのではという一部批判も。
 Reactive Streams
 非同期ストリーム処理のAPIの標準化
 Akka Streams, Reactor, RxJava, Ratpack, vert.xなどが対応。
 Facebook社の開発するクライアントサイド向けのアプリケーションフレームワーク。
 今もっとも勢いがあるフレームワークのひとつ。
 Reactという名前ではあるが、リアクティブプログラミングとはあんまり関係ない。
 GUIにおけるデータバインド機能は古くから存在する。
 データバインド機能は、一種のリアクティブプログラミングであるといえる。
 イベントを時間的に流れてくるデータの無限リ
ストとして扱う。
 イベントに対しても、普通のリストと同じよう
にmap, reduce, filterなどの処理が使える
 Iterator
 Action側からデータソースに対してデータを取
りにいく(Pullスタイル)
 Observable
 データソース側からActionに対してデータを通
知する(Pushスタイル)
Iterator
<T>
Observable
<T>
Action Action
T next() onNext(T)
Pullスタイル Pushスタイル
 Observer
 イベントを受け取る人。監視する人。
 3種類のイベントを利用
 onNext: データ通知
 onError: エラー通知
 onCompleted: 完了通知
 Observable
 イベントを発行する人。監視対象。
 observable.subscribe(observer);
 いろんなメソッドをつなげてかける
observable
.filter(x -> x > 5)
.map(x -> x * x)
.subscribe(x -> print(x));
 Subscription(Disposable)
 subscribeの戻り値
 監視を解除することができる。
var s = observable.subscribe(observer)
s.unsubscribe();
 unsubscribeを呼ばなくても、onCompleted発生
時点で監視は解除される
 Scheduler
 コールバック関数を実行するスレッドを切り替え
ることができる。
 GUIアプリの場合、subscribeを実行するスレッ
ドをUIスレッドに切り替えて、画面の描画をおこ
なう場合などに使える。
 テスト用スケジューラを使うと、実行タイミング
を自在に制御できる。
 Promiseも非同期処理を書きやすくするための手段。
 Promiseが主に1回きりのイベントを取り扱うのに対して、Reactiveではイベントストリームを扱
う。
 RxではPromiseとの相互変換のAPIも用意している。
 Promiseの強み
 ジェネレータ(yield)との相性がよい。
 非同期処理を同期処理のように書くことができる。
 C#, JavaScript, TypeScript, Python
 JavaScriptではブラウザ組み込みになる。
Javaでも標準ライブラリに入ってる。
async void func() {
try {
var x = await something1();
var y = await something2(x);
} catch (Exception ex) {
// エラー処理
}
}
fileSystem.open(fileName, result -> {
if (result.succeeded()) {
result.result().write(buf, 100, x -> {
if (x.succeeded()) {
result.result().close(v -> {
if (v.succeeded()) {
// 正常処理
} else {
// エラー処理
}
});
} else {
// エラー処理
}
});
} else {
// エラー処理
}
});
fileSystem.open(fileName)
.flatMap(file -> file.write(buf, 100)
.flatMap(v -> file.close()))
.subscribe(
x -> /* 正常処理 */,
e -> /* エラー処理 */
);
ノンブロッキングI/OのAPI
を利用してファイル操作をし
ていると、ネストが深くなり
エラー処理も分散してしまう
RxJavaで書き換えると
見通しがよくなった
clickEvents
.buffer(clickEvents.throttle(250))
.map(es -> es.length())
.filter(len -> len == 3)
.subscribe(x -> {
print("トリプルクリック");
});
時間[t]
クリックイベント
throttle
map
filter
buffer
1 3 2
3
250ms
 リトライ処理
Observable.defer(() ->
httpClient.get("/api/products")
)
.retry(5)
.subscribe(
x -> /* 正常に取得できた*/,
e -> /* 5回以上失敗した */
);
 タイムアウト処理
httpClient.get("/api/products")
.timeout(1000)
.take(1)
.subscribe(
x -> /* 正常に取得できた*/,
e -> /* 1秒待っても結果が得られなかった */
);
textChangedEvents
.throttle(250)
.map(data -> data.newValue)
.distinctUntilChanged()
.flatMap(text -> search(text))
.switchLatest()
.subscribe(x -> print(x));
時間[t]
テキスト入力
throttle
flatMap(search)
switchLatest
distict
a
a
ab a
a
ar ariel
arielar
検索ワード
検索結果
 非同期処理を書くときにはPromiseとかReactiveとか使いましょう。
 PromiseとReactiveは競合するものではない。適材適所で使いましょう。
 Reactive Programingはとても楽しいので、ぜひ一度ためしてみてください。
あなたの好きなプログラミング言語でもRx実装があるかも。(なければつくろう!)
 なぜリアクティブプログラミングは重要か。
 やさしいFunctional reactive programming(概要編)
 【翻訳】あなたが求めていたリアクティブプログラミング入門
 The History of Reactive Extensions
 ReactiveX
 "The Reactive Manifesto v2.0" 日本語訳
 非同期ストリーム処理の標準化を目指す "Reactive Streams" とは
 RxMarbles

Reactive