Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
-
Upload
toshiaki-maki -
Category
Technology
-
view
26.362 -
download
3
Transcript of Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
![Page 1: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/1.jpg)
Reactive Webアプリケーション - そしてSpring 5へ
Toshiaki Maki (@making) JJUG CCC 2015 Fall
2015-11-30 #jjug_ccc #ccc_ef3
![Page 2: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/2.jpg)
聞いたことあります?• Reactive Programming? • Reactive Manifest? • Reactive Streams? • Reactive Extensions? • Reactive ... ?
![Page 3: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/3.jpg)
• Reactiveが重要視されてきた背景 • Reactive Streams • Reactive Extensions • Spring 5
今日話すこと
![Page 4: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/4.jpg)
Reactive Extensions(Rx)
Reactive Programming
Reactive Streams Reactor
RxJava
Spring 5
プロラミング パラダイム 仕様(?)
今日話すこと実装
ライブラリSpring
Framework
![Page 5: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/5.jpg)
元ネタ
http://www.slideshare.net/SpringCentral/reactive-web-applications-53170985
http://www.slideshare.net/SpringCentral/introduction-to-reactive-programming
![Page 6: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/6.jpg)
Reactiveが重要視されてきた背景
![Page 8: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/8.jpg)
Amdalの法則
https://en.wikipedia.org/wiki/Amdahl%27s_law
プログラムの並列化による速度の向上は、 プログラムの逐次処理部分によって制限される
![Page 9: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/9.jpg)
Amdalの法則
https://en.wikipedia.org/wiki/Amdahl%27s_law
プログラムの並列化による速度の向上は、 プログラムの逐次処理部分によって制限される
プログラム中の並列実行可能部分が50%だと、いくら並列度を増やしても2倍の性能向上し
か見込めない
![Page 10: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/10.jpg)
スケールアウト戦略
• メモリばかり消費してCPUに空き…
✦ 大量のスレッドプール
✦ブロッキングI/O
![Page 11: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/11.jpg)
ブロッキングコードを 書いていては
ハードにいくら金をかけても性能向上に限界がある
![Page 12: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/12.jpg)
Blocking is evil• ブロッキングコードは並列化の妨げ
• 2大ブロッキング
• リクエストの受信待ち/レスポンスの送信待ち
• DBクエリの結果待ち
![Page 13: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/13.jpg)
Blocking is evil• ブロッキングコードは並列化の妨げ
• 2大ブロッキング
• リクエストの受信待ち/レスポンスの送信待ち
• DBクエリの結果待ち
InputStream OutputStream
JDBC
![Page 14: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/14.jpg)
• IoT
•マイクロサービス
今後のトレンド
![Page 15: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/15.jpg)
• IoT
•マイクロサービス
低速で膨大な リクエスト が予想される
今後のトレンド
![Page 16: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/16.jpg)
• IoT
•マイクロサービス
低速で膨大な リクエスト が予想される
今後のトレンド
Blocking == 💴
![Page 17: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/17.jpg)
Non-Blocking!• 命令型ではなくリスナー/コールバックスタイル
• スレッド数を少なく • →省メモリ • →コンテキストスイッチを減らす • →CPUを有効活用
![Page 18: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/18.jpg)
Reactiveプログラミング• 命令型と異なるプログラミングパラダイム
• 連続的なデータをイベントハンドラで処理する
• データフロー(データ同士の関係性)に着目したイベントドリブンなプログラミング
![Page 19: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/19.jpg)
Reactiveプログラミング• 命令型と異なるプログラミングパラダイム
• 連続的なデータをイベントハンドラで処理する
• データフロー(データ同士の関係性)に着目したイベントドリブンなプログラミング
ノンブロッキングコードを書くのに向いている
![Page 20: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/20.jpg)
最も身近なReactiveプログラミング?
![Page 21: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/21.jpg)
最も身近なReactiveプログラミング?
![Page 22: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/22.jpg)
最も身近なReactiveプログラミング?
![Page 23: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/23.jpg)
最も身近なReactiveプログラミング?
![Page 24: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/24.jpg)
最も身近なReactiveプログラミング?
A, Bの変更に伴い Cも変わる
![Page 25: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/25.jpg)
データフロー
A
B ×2
+ C
A, Bの変更に伴い Cも変わるhttps://speakerdeck.com/okapies/reactive-streams-ru-men-number-jjug
![Page 26: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/26.jpg)
イベントストリーム
x2
+
1 2 4 3
9 6 8 6 5 9
8 4 2 64 2 1 3
A
B
C
![Page 27: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/27.jpg)
イベントストリーム
x2
+
1 2 4 3
9 6 8 6 5 9
8 4 2 64 2 1 3
A
B
C
![Page 28: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/28.jpg)
イベントストリーム
x2
+
1 2 4 3
9 6 8 6 5 9
8 4 2 64 2 1 3
A
B
C
![Page 29: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/29.jpg)
イベントストリーム
x2
+
1 2 4 3
9 6 8 6 5 9
8 4 2 64 2 1 3
A
B
C
![Page 30: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/30.jpg)
イベントストリーム
x2
+
1 2 4 3
9 6 8 6 5 9
8 4 2 64 2 1 3
A
B
C
![Page 31: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/31.jpg)
イベントストリーム
x2
+
1 2 4 3
9 6 8 6 5 9
8 4 2 64 2 1 3
A
B
C
![Page 32: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/32.jpg)
イベントストリーム
x2
+
1 2 4 3
9 6 8 6 5 9
8 4 2 64 2 1 3
A
B
C
![Page 33: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/33.jpg)
命令型
int A = 3;int B = 3;int C = A + B * 2; // 9B = 1;
A, Bが変更されても Cは変わらない
![Page 34: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/34.jpg)
JavaFXの場合@FXML Spinner<Integer> valueA; @FXML Spinner<Integer> valueB; @FXML Label valueC;
private void bind() { IntegerProperty a = new SimpleIntegerProperty(0); IntegerProperty b = new SimpleIntegerProperty(0); NumberBinding c = a.add(b.multiply(2)); // c = a + 2 * b a.bind(this.valueA.valueProperty()); b.bind(this.valueB.valueProperty()); valueC.textProperty().bind(c.asString()); }
http://aoe-tk.hatenablog.com/entry/2015/07/12/173402
![Page 35: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/35.jpg)
![Page 36: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/36.jpg)
![Page 37: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/37.jpg)
A, Bの変更に伴い Cも変わる
![Page 38: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/38.jpg)
Reactive Webアプリケーション
Repository
DB
Service
Controller
![Page 39: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/39.jpg)
Reactive Webアプリケーション
Repository
DB
Service
Controller
![Page 40: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/40.jpg)
Reactive Webアプリケーション
Repository
DB
Service
Controller
Blocking Blocking
![Page 41: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/41.jpg)
Reactive Webアプリケーション
Repository
DB
Service
Controller
Blocking BlockingBlocking他サービス呼び出し
![Page 42: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/42.jpg)
Reactive Streams
![Page 43: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/43.jpg)
Reactive Streams
• http://www.reactive-streams.org/
• 非同期ストリームの標準仕様
• BackPressure付き
![Page 44: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/44.jpg)
Reactive Streamsの動機1. 技術面: データを送り側の勢いが受け取り側の処理速度より速い場合に、データが溢れることを防ぎたい(BackPressure)
2. 開発面: 似たような機能(API)を持つ製品群の相互互換性を持たせたい
![Page 45: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/45.jpg)
関わっている会社• Typesafe • Pivotal • Netflix • RedHat • など
![Page 46: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/46.jpg)
関わっている会社• Typesafe ... Akka Streams • Pivotal ... Reactor • Netflix ... RxJava • RedHat ... Vert.x • など
![Page 47: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/47.jpg)
Reactive Streamsが提供するもの
• 4つのインターフェース
• 仕様ドキュメント
• TCK (仕様をテストするJUnitの親クラス)
![Page 48: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/48.jpg)
public interface Publisher<T> { public void subscribe(Subscriber<? super T> s);}public interface Subscription { public void request(long n); public void cancel();}public interface Subscriber<T> { public void onSubscribe(Subscription s); public void onNext(T t); public void onError(Throwable t); public void onComplete();}public interface Processor<T, R> extends Publisher<T>, Subscriber<R> {}
org.reactivestreams
![Page 49: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/49.jpg)
public interface Publisher<T> { public void subscribe(Subscriber<? super T> s);}public interface Subscription { public void request(long n); public void cancel();}public interface Subscriber<T> { public void onSubscribe(Subscription s); public void onNext(T t); public void onError(Throwable t); public void onComplete();}public interface Processor<T, R> extends Publisher<T>, Subscriber<R> {}
org.reactivestreams
BackPressure
![Page 50: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/50.jpg)
呼び出し順
onSubscribe onNext* (onError | onComplete)?
![Page 51: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/51.jpg)
Subscription SubscriberPublisher Application
![Page 52: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/52.jpg)
Subscription
subscribe(Subscriber)
SubscriberPublisher Application
![Page 53: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/53.jpg)
Subscription
subscribe(Subscriber)
SubscriberPublisher Application
onSubscribe(Subscription)
![Page 54: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/54.jpg)
Subscription
subscribe(Subscriber)
SubscriberPublisher Application
onSubscribe(Subscription)request(1)
![Page 55: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/55.jpg)
Subscription
subscribe(Subscriber)
SubscriberPublisher Application
onSubscribe(Subscription)request(1)onNext(●)
![Page 56: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/56.jpg)
Subscription
subscribe(Subscriber)
SubscriberPublisher Application
onSubscribe(Subscription)request(1)onNext(●)request(2)
![Page 57: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/57.jpg)
Subscription
subscribe(Subscriber)
SubscriberPublisher Application
onSubscribe(Subscription)request(1)onNext(●)request(2)onNext(●)
![Page 58: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/58.jpg)
Subscription
subscribe(Subscriber)
SubscriberPublisher Application
onSubscribe(Subscription)request(1)onNext(●)request(2)onNext(●)onNext(●)
![Page 59: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/59.jpg)
Subscription
subscribe(Subscriber)
SubscriberPublisher Application
onSubscribe(Subscription)request(1)onNext(●)request(2)onNext(●)onNext(●)request(4)
![Page 60: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/60.jpg)
Subscription
subscribe(Subscriber)
SubscriberPublisher Application
onSubscribe(Subscription)request(1)onNext(●)request(2)onNext(●)onNext(●)request(4)onNext(●)
![Page 61: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/61.jpg)
Subscription
subscribe(Subscriber)
SubscriberPublisher Application
onSubscribe(Subscription)request(1)onNext(●)request(2)onNext(●)onNext(●)request(4)onNext(●)onNext(●)
![Page 62: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/62.jpg)
Subscription
subscribe(Subscriber)
SubscriberPublisher Application
onSubscribe(Subscription)request(1)onNext(●)request(2)onNext(●)onNext(●)request(4)onNext(●)onNext(●)onComplete()
![Page 63: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/63.jpg)
Subscription
subscribe(Subscriber)
SubscriberPublisher Application
onSubscribe(Subscription)request(Long.MAX_VALUE)
![Page 64: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/64.jpg)
Subscription
subscribe(Subscriber)
SubscriberPublisher Application
onSubscribe(Subscription)request(Long.MAX_VALUE)onNext(●)
![Page 65: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/65.jpg)
Subscription
subscribe(Subscriber)
SubscriberPublisher Application
onSubscribe(Subscription)request(Long.MAX_VALUE)onNext(●)onNext(●)
![Page 66: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/66.jpg)
Subscription
subscribe(Subscriber)
SubscriberPublisher Application
onSubscribe(Subscription)request(Long.MAX_VALUE)onNext(●)onNext(●)onNext(●)
![Page 67: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/67.jpg)
Subscription
subscribe(Subscriber)
SubscriberPublisher Application
onSubscribe(Subscription)request(Long.MAX_VALUE)onNext(●)onNext(●)onNext(●)onNext(●)
![Page 68: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/68.jpg)
Subscription
subscribe(Subscriber)
SubscriberPublisher Application
onSubscribe(Subscription)request(Long.MAX_VALUE)onNext(●)onNext(●)onNext(●)onNext(●)onNext(●)
![Page 69: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/69.jpg)
Subscription
subscribe(Subscriber)
SubscriberPublisher Application
onSubscribe(Subscription)request(Long.MAX_VALUE)onNext(●)onNext(●)onNext(●)onNext(●)onNext(●)onComplete()
![Page 70: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/70.jpg)
Subscription
subscribe(Subscriber)
SubscriberPublisher Application
onSubscribe(Subscription)request(1)onNext(●)request(2)onNext(●)onNext(●)request(4)
![Page 71: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/71.jpg)
Subscription
subscribe(Subscriber)
SubscriberPublisher Application
onSubscribe(Subscription)request(1)onNext(●)request(2)onNext(●)onNext(●)request(4)💣💥
![Page 72: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/72.jpg)
Subscription
subscribe(Subscriber)
SubscriberPublisher Application
onSubscribe(Subscription)request(1)onNext(●)request(2)onNext(●)onNext(●)request(4)onError(Throwable)
💣💥
![Page 73: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/73.jpg)
RxJavaからinspired
RxJava Reactive StreamsObservable<T> Publisher<T>Observer<T> Subscriber<T>Subscription Subscription
![Page 74: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/74.jpg)
Non BlockingなAPI• TやList<T>の代わりにPublisher<T>を返す
Blocking Non BlockingUser
get(String name)Publisher<User>get(String name)
List<User> allFriends(User user)
Publisher<User> allFriends(User user)
![Page 75: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/75.jpg)
実装例 (Publisher)public class IntPublisher implements Publisher<Integer> { @Override public void subscribe(Subscriber<? super Integer> s) { s.onSubscribe(new Subscription() { Iterator<Integer> it = IntStream.range(0, 10) .boxed().iterator(); @Override public void request(long n) { for (int i = 0; i < n; i++) { if (it.hasNext()) { s.onNext(it.next()); } else { s.onComplete(); break; }}} @Override public void cancel() {} });}}
![Page 76: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/76.jpg)
実装例 (Subscriber)public class IntSubscriber implements Subscriber<Integer> { Subscription subscription; int req = 1; // AtomicIntegerにすべき @Override public void onSubscribe(Subscription s) { subscription = s; s.request(req); } @Override public void onNext(Integer integer) { System.out.println("Next -> " + integer); if (--req == 0) { req = new Random().nextInt(10) + 1; subscription.request(req); } } @Override public void onError(Throwable t) { /**/ } @Override public void onComplete() { System.out.println("Complete!"); } }
![Page 77: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/77.jpg)
使用例Publisher<Integer> publisher = new IntPublisher();Subscriber<Integer> subscriber = new IntSubscriber();publisher.subscribe(subscriber);// Next -> 1// Next -> 2// Next -> 3// Next -> 4// Next -> 5// Next -> 6// Next -> 7// Next -> 8// Next -> 9// Next -> 10// Complete!
![Page 78: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/78.jpg)
使用例Publisher<Integer> publisher = new IntPublisher();Subscriber<Integer> subscriber = new IntSubscriber();publisher.subscribe(subscriber);// Next -> 1// Next -> 2// Next -> 3// Next -> 4// Next -> 5// Next -> 6// Next -> 7// Next -> 8// Next -> 9// Next -> 10// Complete!
IntPublisher/IntSubscriberはインターフェースを実装しているだけ
で、実は仕様を満たしていない (TCKを通らない)
![Page 79: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/79.jpg)
Hot / Cold• Hot Stream
• ずっと続いていて途中から見はじめるもの • 株価情報、タイムライン、マウスイベント、タイマーイベント、WebSocket、Server-Sent Events、メッセージキュー
• Cold Stream • 再現可能で、最初から最後まで見れるもの • 配列・リスト、ファイル、データベース、計算結果(Future)
![Page 80: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/80.jpg)
Reactive Streamsの仕様
• Subscriberは非同期でも同期でもよい。ただし、ノンブロッキングでないといけない
![Page 81: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/81.jpg)
実装プロダクト(フレームワーク)
• Reactor (Pivotal) • RxJava (Netflix) • Akka Streams (Typesafe) • Vert.x (Redhat) • Ratpack • Quasarhttp://www.reactive-streams.org/announce-1.0.0
![Page 82: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/82.jpg)
実装データアクセスライブラリ• MongoDB (公式) • Apache Kafka • Rabbit MQ (Scalaのみ) • Slick3 (Scala) • CouchDB (RxJava only) • PostgreSQL (RxJava only、開発中?) • Spark (検討中? SPARK-10420) • など
![Page 83: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/83.jpg)
MongoDB
• http://mongodb.github.io/mongo-java-driver-reactivestreams/
• MongoDB公式でReactive Streams APIがサポートされている
• チュートリアルがあるのでわかりやすい
![Page 84: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/84.jpg)
MongoDBMongoClient client = MongoClients.create( "mongodb://localhost"); MongoDatabase db = client.getDatabase("mydb"); MongoCollection<Document> collection = db.getCollection("test");// InsertDocument doc = new Document("message", "Hello!"); Publisher<Success> insert = collection.insertOne(doc); insert.subscribe(new PrintSubscriber<>("result=%s"));
// SelectPublisher<Document> docs = collection.find(); docs.subscribe(new PrintDocumentSubscriber());
![Page 85: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/85.jpg)
MongoDB// Bulk OperationPrintSubscriber<BulkWriteResult> subscriber = new PrintSubscriber<>("Bulk write results: %s"); collection.bulkWrite(Arrays.asList( new InsertOneModel<>(new Document("_id", 4)), new InsertOneModel<>(new Document("_id", 5)), new InsertOneModel<>(new Document("_id", 6)), new UpdateOneModel<>(new Document("_id", 1), new Document("$set", new Document("x", 2))), new DeleteOneModel<>(new Document("_id", 2)), new ReplaceOneModel<>(new Document("_id", 3), new Document("_id", 3).append("x",4)))) .subscribe(subscriber);
![Page 86: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/86.jpg)
Apache Kafka
• https://github.com/softwaremill/reactive-kafka
• Scalaで実装されている。Java用APIも用意されている。
![Page 87: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/87.jpg)
Apache KafkaReactiveKafka kafka = new ReactiveKafka(); ActorSystem system = ActorSystem.create("ReactiveKafka");
Publisher<MessageAndMetadata<byte[], String>> topicA = kafka.consume(new PropertiesBuilder.Consumer( broker, zk, "topicA","group", decoder) .build(), system);
topicA.subscribe(subscriber);
![Page 88: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/88.jpg)
PostgreSQL
• https://github.com/alaisi/postgres-async-driver
• https://github.com/mauricio/postgresql-async
![Page 89: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/89.jpg)
PostgreSQLDb db = new ConnectionPoolBuilder().hostname("localhost").port(5432).database("demo").username("postgres").password("").poolSize(20).build();// RxJava's ObservableObservable<Row> result = db.queryRows("select id,value from demo");result.subscribe(...);// to Reactive StreamsPublisher<Row> publisher = RxReactiveStreams.toPublisher(result);publisher.subscribe(...);
![Page 90: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/90.jpg)
Publisher単体だと使いにくい• Publisherはただのコールバック
• map、flatMap、merge、filer、take、zipといっった合成(compose)や変換(transform)のためのAPIがない → コールバック地獄に
• Publisherはインターフェースでしかないので実装ライブラリ側で便利なAPIを提供可能。
![Page 91: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/91.jpg)
コールバック地獄
• もっと命令的に書きたい
• ComposableなAPIが欲しい(Reactive Streamsの範疇外)
![Page 92: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/92.jpg)
Reactive Extensions
![Page 93: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/93.jpg)
Reactive Extensions(Rx)
• 元々はMicrosoftのでErik Meijerによって.NET(LINQ)向け開発されたライブラリ
• Observerパターンでイベントストリームを扱う • イベントストリームを操作(変換、フィルタ、合成など)する豊富なAPI群
• 多言語対応(Java, JavaScript, .NET, Swiftなど)
http://reactivex.io/
![Page 94: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/94.jpg)
map
![Page 95: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/95.jpg)
flatMap
![Page 96: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/96.jpg)
filter
![Page 97: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/97.jpg)
take
![Page 98: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/98.jpg)
merge
![Page 99: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/99.jpg)
zip
![Page 100: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/100.jpg)
combileLatest
![Page 101: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/101.jpg)
buffer
![Page 102: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/102.jpg)
RxJava• Netflix社が開発したRxのJava版 • Observable/Observer • Observableに対して豊富なOperation APIを提供
Observable.just('a', 'b', 'c') .take(2) .map(Character::toUpperCase) .consume(System.out::print); // AB
![Page 103: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/103.jpg)
RxJava• バージョン1.0ではReactive Streamsをnativeサポートしていない。Publisher <-> Observableアダプターが必要
• バージョン2.0でReactive Streams対応予定
// Publisher <-> ObservablePublisher<String> publisher = RxReactiveStreams.toPublisher(observable);Observable<String> observable = RxReactiveStreams.toObservable(publisher);
![Page 104: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/104.jpg)
Reactor• Pivotal社が開発
• LMAX Disruptorの高性能なRing Bufferを使用している • Spring Frameworkの一部の機能で使用されている
• Reactive StreamsのPublisher + Composable API → reactor.rx.Stream
Streams.just('a', 'b', 'c') .take(2) .map(Character::toUpperCase) .consume(System.out::print); // AB
![Page 105: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/105.jpg)
Reactor Projectshttp://projectreactor.io/docs/reference/#_about_the_project
![Page 106: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/106.jpg)
Reactive StreamsとReactor Streamsの関係
BroadCaster
Action
Stream
Processor
Subscriber Publisher
Consumer
ClassInterface
extends implements
Reactive Streams
Reactor
Promise
![Page 107: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/107.jpg)
Reactor Streamsへの変換import reactor.rx.Stream;import reactor.rx.Streams;
// Streamの要素を直接指定(Cold)Stream<String> stream = Streams.just("a", "b");
// T[]やIterable<T>からStream<T>への変換(Cold)Stream<String> stream = Streams.from(value);
// Publisher<T>からStream<T>へ変換Stream<String> stream = Streams.wrap(publisher);
![Page 108: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/108.jpg)
// Subscription.request(Long.MAX_VALUE)相当// consumeに渡すラムダ式がonNextで実行されるstream.consume(s -> System.out.println(s));
// Subscription.request(2)を繰り返すstream.capacity(2) .consume(s -> System.out.println(s));
// デバッグログ出力stream.log() .consume(s -> System.out.println(s));
![Page 109: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/109.jpg)
Reactive Streamsの仕様を簡単に満たすヘルパー
List<Integer> items = /* ... */;Publisher<Integer> publisher = PublisherFactory.forEach((subscriber) -> { Iterator<Integer> iterator = subscriber.context(); if (iterator.hasNext()) { subscriber.onNext(iterator.next()); } else { subscriber.onComplete(); } }, subscriber -> items.iterator());
![Page 110: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/110.jpg)
reactor.rx.Streamを使うことで Reactive Streamsを Reactive Extensionsで操作できる
![Page 111: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/111.jpg)
Kafka + Reactorで足し算Publisher<MessageAndMetadata<byte[], String>> topicA = kafka.consume(new PropertiesBuilder.Consumer( broker, zk, "a", "group", decoder) .build(), system); Publisher<MessageAndMetadata<byte[], String>> topicB = kafka.consume(new PropertiesBuilder.Consumer( broker, zk, "b", "group", decoder) .build(), system);Publisher<Integer> a = Streams.wrap(topicA) .map(x -> Integer.valueOf(x.message())); Publisher<Integer> bx2 = Streams.wrap(topicB) .map(x -> Integer.valueOf(x.message())) .map(x -> x * 2);Streams.combineLatest(a, bx2, tpl -> tpl.getT1()+tpl.getT2()) .consume(c -> { System.out.println("a + b * 2 = " + c); });
![Page 112: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/112.jpg)
Kafka + Reactorで足し算
$ echo '3' | kafkacat -P -t a -b localhost:9092$ echo '3' | kafkacat -P -t b -b localhost:9092
$ echo '1' | kafkacat -P -t b -b localhost:9092
a + b * 2 = 5
a + b * 2 = 9
![Page 113: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/113.jpg)
Reactorでコナミコマンド// Create a "Hot" streamBroadcaster<String> stream = Broadcaster.create(Environment.get());stream.filter(x -> x.length() == 1) .buffer(10, 1) // 10イベント分を1つずらしでまとめる .map(s -> "↑".equals(s.get(0)) && "↑".equals(s.get(1)) && """.equals(s.get(2)) && """.equals(s.get(3)) && "←".equals(s.get(4)) && "#".equals(s.get(5)) && "←".equals(s.get(6)) && "#".equals(s.get(7)) && "A".equals(s.get(8)) && "B".equals(s.get(9))) .consume(isKonami -> { System.out.println(isKonami ? "Konami!" : "NG"); });
![Page 114: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/114.jpg)
Reactorでコナミコマンドstream.onNext("A"); stream.onNext("↑"); stream.onNext("↑"); stream.onNext("""); stream.onNext("""); stream.onNext("←"); stream.onNext("#"); stream.onNext("←"); stream.onNext("#"); stream.onNext("A"); stream.onNext("B"); stream.onNext("←");
NGKonami!NG
コナミコマンド
HotStreamをエミュレート
![Page 115: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/115.jpg)
外部サービス呼び出し (Blocking)
public interface LinkedInService {List<String> findUsers(String keyword);LinkedInProfile getConnection(String id);
}
public interface TwitterService {TwitterProfile getUserProfile(String id);
}
public interface FacebookService {FacebookProfile getUserProfile(String id);
}
![Page 116: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/116.jpg)
外部サービス呼び出し (NonBlocking)
public interface LinkedInService {Stream<String> findUsers(String keyword);Stream<LinkedInProfile> getConnection(String id);
}
public interface TwitterService {Stream<TwitterProfile> getUserProfile(String id);
}
public interface FacebookService {Stream<FacebookProfile> getUserProfile(String id);
}
![Page 117: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/117.jpg)
flatMaplinkedInService.findUsers("JJUG") .take(5) .flatMap(userName -> linkedInService.getConnections(userName) .take(3) .flatMap(connection -> { String twitterId = connection.getTwitterId(); Publisher<TwitterProfile> twitterProfile = twitterService.getUserProfile(twitterId); String facebookId = connection.getFacebookId(); Publisher<FacebookProfile> facebookProfile = facebookService.getUserProfile(facebookId); return Streams.zip(twitterProfile, facebookProfile, (tp, fp) -> new UserConnectionInfo( userName, connection, tp, fp)); }) ) .subscribe(System.out::println);
http://www.slideshare.net/SpringCentral/introduction-to-reactive-programming/60
![Page 118: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/118.jpg)
Reactor or RxJava ?Reactor RxJava
• Reactive StreamsをNativeサポート
• Spring連携 • Reactive Extensionsのサブセット
•Reactive Exensionsをフルセットでサポート
•他言語対応 • Reactive Streamsはアダプター経由
![Page 119: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/119.jpg)
Reactive Streamsのメリット• 非同期サポートライブラリを作りやすい
![Page 120: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/120.jpg)
Reactive Streamsのメリット• 非同期サポートライブラリを作りやすい• async-db-driver
• Publisher/Subscriberのみを使ったコアライブラリ • async-db-driver-reactor
• ReactorのStreamにラップ • async-db-driver-rxjava
• RxJavaのObservableにラップ • ...
https://github.com/ReactiveX/RxJava/wiki/Reactive-Streams#recommended-approach
![Page 121: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/121.jpg)
package com.example.db.driver;import org.reactivestreams.Publisher;public class Database {public Publisher getValue(String key) { /* ... */ }
}
package com.example.db.driver.reactor;public class Database {public Stream getValue(String key) {
return Streams.wrap(coreDatabase.getValue(key));}
}package com.example.db.driver.rxjava;public class Database {public Observable getValue(String key) { return RxReactiveStreams.toObservable( coreDatabase.getValue(key));}
}
RxJava用
Reactor用
Core API
![Page 122: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/122.jpg)
すべてがPublisherで繋がる
Repository
DB
Service
Controller
Publisher Publisher Publisher
PublisherPublisherPublisher
![Page 123: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/123.jpg)
すべてがPublisherで繋がる
Repository
DB
Service
Controller
Publisher Publisher Publisher
PublisherPublisherPublisher
![Page 124: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/124.jpg)
すべてがPublisherで繋がる
Repository
DB
Service
Controller
Publisher Publisher Publisher
PublisherPublisherPublisher
ここは?
![Page 125: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/125.jpg)
Spring 5
![Page 126: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/126.jpg)
Spring 5• Q4 2016 • JDK 9サポート • Java 8がベースライン • HTTP 2対応 • Reactive対応 • JUnit5対応
![Page 127: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/127.jpg)
Spring 5• Q4 2016 • JDK 9サポート • Java 8がベースライン • HTTP 2対応 • Reactive対応 • JUnit5対応
![Page 128: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/128.jpg)
Java WebアプリケーションのReactive対応?
• Servlet APIは至るところでBlocking • InputStream/OutputStream • getParameters/getParts • sendError• ...
![Page 129: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/129.jpg)
昨今のNoBlocking対応 フレームワーク
• Play Framework • Vert.x • Ratpack • Reactor Net • RxNetty
脱Servlet API組 ↓
Netty利用
![Page 130: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/130.jpg)
Servletはダメな子なのか
![Page 131: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/131.jpg)
Servletはダメな子なのか
• Servlet 3.0 … 非同期処理サポート
![Page 132: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/132.jpg)
Servletはダメな子なのか
• Servlet 3.0 … 非同期処理サポート
• Servlet 3.1 … Non-Blocking APIサポート
![Page 133: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/133.jpg)
Servlet 3.0 非同期処理サポート
void doGet(req, res) { OutputStream out = res.getOutputStream(); AsyncContext ctx = req.startAsync(); doAsyncREST(req).thenAccept(json -> { out.write(json); ctx.complete(); });}
http://www.slideshare.net/SimoneBordet/servlet-31-async-io
![Page 134: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/134.jpg)
Servlet 3.0 非同期処理サポート
void doGet(req, res) { OutputStream out = res.getOutputStream(); AsyncContext ctx = req.startAsync(); doAsyncREST(req).thenAccept(json -> { out.write(json); // Blocking!! ctx.complete(); });}
http://www.slideshare.net/SimoneBordet/servlet-31-async-io
![Page 135: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/135.jpg)
Servlet 3.1 Non-Blocking APIサポート
• リクエストの読み込み/レスポンスの書き込みをNon-Blockingに行うためのAPIが追加された
• 以下のシーンで効果的 • ファイルアップロード/ダウンロード • 低速ネットワークからの大量アクセス(モバイル、IoT)
![Page 136: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/136.jpg)
void doGet(req, res) { OutputStream out = res.getOutputStream(); AsyncContext ctx = req.startAsync(); out.setWriteListener(new WriteListener() { void onWritePossible() { while (on.isReady()) { // ... ctx.complete(); } } });}
http://www.slideshare.net/SimoneBordet/servlet-31-async-io
![Page 137: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/137.jpg)
Hello Worldサーブレット@WebServlet(urlPatterns = "/hello" , asyncSupported = true)public class HelloServlet extends HttpServlet { @Override public void service(HttpServletRequest req, HttpServletResponse resp) { AsyncContext ctx = req.startAsync(req, resp); ServletInputStream input = req.getInputStream(); ReadListener readListener = new ReadListenerImpl(input, resp, ctx); input.setReadListener(readListener);}
![Page 138: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/138.jpg)
class ReadListenerImpl implements ReadListener { // ... private final StringBuilder sb = new StringBuilder(); public ReadListenerImpl(ServletInputStream input, HttpServletResponse resp, AsyncContext ctx) {/* ... */} public void onDataAvailable() throws IOException { int len = 0; byte b[] = new byte[1024]; while (input.isReady() && !input.isFinished() && (len = input.read(b)) != -1) { sb.append(new String(b, 0, len)); } } public void onAllDataRead() throws IOException { ServletOutputStream output = resp.getOutputStream(); WriteListener writeListener = new WriteListenerImpl(output, ctx); output.setWriteListener(writeListener); } public void onError(Throwable th) { ctx.complete(); th.printStackTrace(); }}
![Page 139: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/139.jpg)
class WriteListenerImpl implements WriteListener { private final ServletOutputStream output; private final AsyncContext ctx; public WriteListenerImpl(ServletOutputStream output, AsyncContext ctx) { this.output = output; this.ctx = ctx; } public void onWritePossible() throws IOException { output.print("Hello World!"); output.flush(); ctx.complete(); } public void onError(Throwable th) { th.printStackTrace(); }}
![Page 140: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/140.jpg)
Block
Servlet
![Page 141: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/141.jpg)
Servlet
ReadListener
WriteListener
![Page 142: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/142.jpg)
Servlet
ReadListener
WriteListener
![Page 143: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/143.jpg)
書くのが辛い
• Non-Blockingの方が5倍コード量が多い
• isReady, isFinishedの制御が難しい
• ついgetParameterするとBlock...
http://www.slideshare.net/SimoneBordet/servlet-31-async-io
![Page 144: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/144.jpg)
Spring Reactive
• Spring 5のReactive対応向け実験プロジェクト • 開発メンバー
• Rossen Stoyanchev (Spring MVC) • Stephane Maldini (Reactor, Reactive Streams) • Arjen Poutsma (MVCのREST対応, Spring WS) • Sébastien Deleuze (MVCのScriptEngine対応) • Brian Clozel (MVCの静的リソースハンドリング対応)
https://github.com/spring-projects/spring-reactive
![Page 145: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/145.jpg)
Servlet31HttpHandlerAdapter
• HttpServlet実装
• ReadListener/WriteListenerをObserverパターンで実装
• Reactive Streams(Publisher/Subscriber)を使用
![Page 146: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/146.jpg)
• ReadListener→Publisher
• WriteListener→Subscriber
Servlet31HttpHandlerAdapter
https://github.com/spring-projects/spring-reactive/tree/master/src/main/java/org/springframework/http/server/servlet31
![Page 147: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/147.jpg)
Instead of ...
interface ServerHttpRequest extends HttpRequest { InputStream getBody();}
interface ServerHttpResponse extends HttpMessage { OutputStream getBody();}
![Page 148: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/148.jpg)
Use Publisher
interface ReactiveServerHttpRequest extends HttpRequest { Publisher<ByteBuffer> getBody();}
interface ReactiveServerHttpResponse extends HttpMessage { Publisher<Void> setBody(Publisher<ByteBuffer> pub);}
![Page 149: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/149.jpg)
Spring MVCのアーキテクチャ
DispatcherServlet
<<IF>> HandlerAdapter
<<IF>> HandlerMapping
Handler (Object)
フレームワーク アプリケーション
org.springframework.web.servletパッケージ
これまでの
![Page 150: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/150.jpg)
Spring MVCのアーキテクチャ
DispatcherServlet
RequestMappingHandlerAdapter
RequestMappingHandlerMapping
@RequestMapping
HttpMessageConverter
org.springframework.web.servlet.mvc.method.annotationパッケージ
これまでの
![Page 151: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/151.jpg)
Spring MVCのアーキテクチャ
DispatcherServlet
RequestMappingHandlerAdapter
RequestMappingHandlerMapping
@RequestMapping
HttpMessageConverter
org.springframework.web.servlet.mvc.method.annotationパッケージ
所謂、 Controllerクラス
これまでの
![Page 152: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/152.jpg)
Spring Reactiveのアーキテクチャ
<<IF>> HandlerAdapter
<<IF>> HandlerMapping
Handler (Object)
フレームワーク アプリケーション
org.springframework.web.reactiveパッケージ
Servlet31HttpHandlerAdapter
<<IF>> Reactive
HttpHandeler
![Page 153: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/153.jpg)
Servlet31HttpHandlerAdapter RequestMapping
HandlerAdapter
RequestMappingHandlerMapping
@RequsetMapping
Encoder/Decoder
Spring Reactiveのアーキテクチャorg.springframework.web.reactive.method.annotationパッケージ
DispatcherHandler
![Page 154: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/154.jpg)
RequestMappingHandlerAdapter
RequestMappingHandlerMapping
@RequsetMapping
Encoder/Decoder
Spring Reactiveのアーキテクチャorg.springframework.web.reactive.method.annotationパッケージ
Servlet31HttpHandlerAdapter
DispatcherHandler
Spring MVCと同じプログラミングモデルで アプリケーションを記述できる
![Page 155: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/155.jpg)
Spring Reactiveのアプローチ
Reactor Net ReactorHttpHanderAdapter
RxNetty RxNettyHttpHandlerAdapter
Undertow UndertowHttpHandlerAdapter
Servlet31HttpHandlerAdapter
Reactive Streams
@Controller
Jetty
Tomcat Publisher
ReactiveHttpHandeler
![Page 156: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/156.jpg)
Spring Reactiveのアプローチ
Reactor Net ReactorHttpHanderAdapter
RxNetty RxNettyHttpHandlerAdapter
Undertow UndertowHttpHandlerAdapter
Servlet31HttpHandlerAdapter
Reactive Streams
@Controller
Jetty
Tomcat Publisher
ReactiveHttpHandeler
Servletコンテナ以外の選択肢もある
![Page 157: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/157.jpg)
Spring MVCのController
@RequestMapping("/")@ResponseBodyPerson hello(@RequestBody Person req) { // ...}
これまでの
![Page 158: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/158.jpg)
Spring ReactiveのController
@RequestMapping("/")@ResponseBodyPublisher<Person> hello( @RequestBody Publisher<Person> req) { // ...}
![Page 159: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/159.jpg)
Reactive Webアプリケーション
Repository
DB
Service
Controller
Publisher Publisher Publisher
PublisherPublisherPublisher
![Page 160: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/160.jpg)
Reactive Webアプリケーション
Repository
DB
Service
Controller
Publisher Publisher Publisher
PublisherPublisherPublisher
Spring Reactive
Reactive Extensions
Reactive Streams
![Page 161: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/161.jpg)
絶賛開発中
• Reactive Clientの実装
• Filter相当の実装
• Progressive HTML renderingの検討
![Page 162: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/162.jpg)
Springは Java EEの代替ではありません
![Page 163: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/163.jpg)
落穂拾い
![Page 164: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/164.jpg)
java.util.concurrent.Flow
• Reactive StreamsがJDK 9に入ります • Flow.Publisher• Flow.Subscriber• Flow.Subscription• Flow.Processor
• http://openjdk.java.net/jeps/266 • http://gee.cs.oswego.edu/dl/jsr166/dist/docs/java/util/concurrent/Flow.html
@author Doug Lea
![Page 165: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/165.jpg)
j.u.c.Flow <-> Reactive Streams• ブリッジ作成を検討中 • https://github.com/reactive-streams/reactive-streams-jvm/issues/294
import java.util.concurrent.Flow;import org.reactivestreams.Publisher;
// j.u.c.Flow -> Reactive StreamsPublisher<T> toReactive(Flow.Publisher<>T);// Reactive Streams -> j.u.c.FlowFlow.Publisher<T> toFlow(Publisher<T>);
![Page 166: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/166.jpg)
Servlet 4
• HTTP2とReactive Streams (Back Pressure)の連携案
• JDK9にj.u.c.Flowが入ったため、御蔵入りの模様
https://java.net/projects/servlet-spec/lists/jsr369-experts/archive/2015-08/message/1
![Page 167: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/167.jpg)
まとめ• Blocking ==💴な時代がきている • Non-Blocking化を助けるReactiveなパラダイム • 非同期ストリーム標準 Reactive Streams • イベントストリームの変換・合成 Reactive Extensions
• Reactive Webアプリケーション向けフレームワークSpring ReactiveがSpring 5に向けて開発中
![Page 168: Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3](https://reader034.fdocument.pub/reader034/viewer/2022042605/587004d21a28ab427f8b5cbd/html5/thumbnails/168.jpg)
まとめ• Blocking ==💴な時代がきている • Non-Blocking化を助けるReactiveなパラダイム • 非同期ストリーム標準 Reactive Streams • イベントストリームの変換・合成 Reactive Extensions
• Reactive Webアプリケーション向けフレームワークSpring ReactiveがSpring 5に向けて開発中
Spring Framework を使っていきましょう