node.js 実践非同期処理

Post on 28-Jul-2015

1.163 Views

Category:

Internet

3 Downloads

Preview:

Click to see full reader

TRANSCRIPT

リアルタイムアクションゲームから見る

Node.js 実践非同期処理

2015/05/19Daiki Taniguchi (@kidach1)

Akatsuki inc.

kidach1

・Github https://github.com/kidach1

・Twitter https://twitter.com/kidach1

・Qiita http://qiita.com/kidach1

・Node / JavaScript / TypeScript  Ruby / Rails Dvorak Keyboard

Agenda

・何を作っているか・Nodeにおける非同期処理手法 ・Promise ・Generator・非同期処理実践・テスト

Products

・2D横スクロールアクション・マルチプレイ ・4人同時対戦 ・座標同期型 ・プレイヤーマッチング (Rating / Keyword)

Architecture

Sequence (rough)

Platform / Protocal / Language

・Node.js・WebSocket・JavaScript / TypeScript

Node.js

・SingleThread・Non-blacking・EventDriven

Node.js

・SingleThread・Non-blacking・EventDriven

→ websocket(双方向通信)との相性 ◎

Node.js

Node.js

Callback Hell

Solution

最近のjs非同期処理 PromiseとGeneratorの共存

http://qiita.com/kidach1/items/d997df84a0ede39d76ad

Promise・非同期処理と操作を抽象化したAPI・then chain ・thenable・もともと初期のNodeには実装されていた →deprecated

 →ブラウザ ( jQuery.Deffered() )

 →ES6でPromiseA+として復活・ES6系機能は--harmony optionが必要(v0.12)  Node.jsのv0.12の時に harmony はdefaultにならないという結論になりました。 - from scratch  http://yosuke-furukawa.hatenablog.com/entry/2014/01/31/153207

Promise

・ある非同期処理

Promise

・Promiseオブジェクトでくるむ

・基本呼び出し

Promise

・基本呼び出し

$ time node --harmony promise.jsSync 1Async 1# node --harmony promise.js 0.05s user 0.05s system 8% cpu 1.179 total

Promise

・直列処理

Promise

・直列処理

$ time node --harmony promise.jsSync 1Sync 2Sync 3# node --harmony promise.js 0.06s user 0.06s system 3% cpu 3.218 total

Promise

・直列処理

$ time node --harmony promise.jsSync 1Sync 2Sync 3# node --harmony promise.js 0.06s user 0.06s system 3% cpu 3.218 total

Promise

・並列処理

Promise

・並列処理

$ time node --harmony promise.jsSync 1[ ‘Async 1’, ‘Async 2’, ‘Async 3’ ]# node --harmony promise.js 0.07s user 0.03s system 8% cpu 1.079 total

Promise

・並列処理

$ time node --harmony promise.jsSync 1[ ‘Async 1’, ‘Async 2’, ‘Async 3’ ]# node --harmony promise.js 0.07s user 0.03s system 8% cpu 1.079 total

Promise

Generator

・ES6・co-routine・非同期処理を同期処理っぽく(縦に)書く・yeild/next で処理の中断/再開  ・yeildables・try~catch

Generator

・yeild/next  ・処理の中断/再開 ・値の送信/受信

Generator

・yeild/next  ・処理の中断/再開 ・値の送信/受信

$ time node --harmony generator.jsSync 1Async 1Async 2Async 3# node --harmony generator.js 0.07s user 0.03s system 2% cpu 3.099 total

Generator

・yeild/next  ・処理の中断/再開 ・値の送信/受信

$ time node --harmony generator.jsSync 1Async 1Async 2Async 3# node --harmony generator.js 0.07s user 0.03s system 2% cpu 3.099 total

・縦に書けて良い!が・・・ ・送信/受信(next / yield)を辿るのは辛い ・generatorオブジェクトを隠蔽したい

Generator

co

https://github.com/tj/co

co

https://github.com/tj/co

Generator

Generator

Generator

・yieldに渡すメソッドのインターフェースは?

cohttps://github.com/tj/co

cohttps://github.com/tj/co

thenable is yieldables.

・直列処理

Generator with co

・直列処理

Generator with co

$ time node --harmony generator.jsSync 1Async 1Async 2Async 3# node --harmony generator.js 0.06s user 0.02s system 2% cpu 3.081 total

・直列処理

Generator with co

・直列処理

Generator with co

$ time node --harmony generator.jsSyncaSyNcASYNCasync# node --harmony generator.js 0.07s user 0.02s system 2% cpu 3.074 total

・Error Handling

Generator

・Error Handling

Generator

・Error Handling

$ time node --harmony generator.jsSync 1Error: err!# node --harmony generator.js 0.08s user 0.03s system 10% cpu 1.103 total

Generator

・Error Handling

Promise

・Error Handling

$ time node --harmony promise.jsSync 1Error: err!# node --harmony promise.js 0.07s user 0.03s system 8% cpu 1.076 total

Promise

非同期処理実例

- ユーザー情報のセット- レーティングごとまたは指定ルームNoごとのユーザー一覧の更新- 同一ルームNoのユーザー/レートの近いユーザー(候補者)の取得- 候補者からマッチング相手の絞込み- マッチングしたことを各ユーザーに通知

・プレイヤーマッチング処理 (Promise ver)

Examples

Examples

・プレイヤーマッチング処理 (callback ver)

・プレイヤーマッチング処理 (Promise ver)

Examples

・プレイヤーマッチング処理 (Promise ver)

Examples

・Promise objcet

Examples

・プレイヤーマッチング処理 (Generator ver)

Examples

・プレイヤーマッチング処理 (Promise ver)

Examples

- roomに終了済ユーザー情報をセット- 全員終了済かどうか判定- 終了済ならroomに通知

・ゲーム終了判定処理

Examples

・ゲーム終了判定処理 (Promise ver)

Examples

・ゲーム終了判定処理 (Generator ver)

Examples

- socket.idからユーザー情報/ルーム情報を取得- ルーム情報からルームメンバーを取得- メンバーにdisconnectを通知- ルーム情報からユーザー情報を除去

・プレイヤーdisconnect時の処理

Examples

・プレイヤーdisconnect時の処理 (Promise ver)

Examples

・プレイヤーdisconnect時の処理 (Promise ver)

Examples

・プレイヤーdisconnect時の処理 (Generator ver)

Examples

非同期処理のテスト

Testing

・接続シーケンスのシミュレート ・Mocha / should http://mochajs.org/

 ・高機能TestingFW & matcher・sinon http://sinonjs.org/

 ・mock, stub

・CONNECTの後にCONNECTEDが返却されること

Testing

・discoonectが同一ルームのメンバーに通知されること

Testing

・discoonectが同一ルームのメンバーに通知されること

Testing

・discoonectが同一ルームのメンバーに通知されること

Testing

Testing

・discoonectが別ルームのメンバーに通知されないこと

Testing

・discoonectが別ルームのメンバーに通知されないこと

Testing

・discoonectが別ルームのメンバーに通知されないこと

・Client Class

Testing

まとめ

・thenable is yieldables ・個々の処理はPromiseベースでくるんでおき ・Promiseで事足りるならそのまま ・複雑性が増しそうならgeneratorの世界を訪れる

まとめ

・thenable is yieldables ・個々の処理はPromiseベースでくるんでおき ・Promiseで事足りるならそのまま ・複雑性が増しそうならgeneratorの世界を訪れる

→ 気軽に行き来出来る!

PromiseとGeneratorで気持ち良い非同期処理を!

Questions

Appendix

Promise 内部実装イメージ

 $  node  promise.js                                                                                                                                                  42

Promise 内部実装イメージ

 $  node  promise.js                                                                                                                                                  42

Promise 内部実装イメージ

 $  node  promise.js                                                                                                                                                  42

Promise 内部実装イメージ

 $  node  promise.js                                                                                                                                                  42

Promise 内部実装イメージ

 $  node  promise.js                                                                                                                                                  42

Promise 内部実装イメージ

 $  node  promise.js                                                                                                                                                  42

Promise 内部実装イメージ

 $  node  promise.js                                                                                                                                                  42

Demo

Generator

Stream

・サイズの大きいdataを取り扱うI/O ・dataをchunkに分割 ・メモリ効率 ・パフォーマンス  ・読み込みながら(並列的に)別処理 ・優れたインターフェース  ・pipeで繋ぐ

Stream

top related