Reactive Programming

4,394 views

Published on

Published in: Technology
0 Comments
26 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
4,394
On SlideShare
0
From Embeds
0
Number of Embeds
246
Actions
Shares
0
Downloads
41
Comments
0
Likes
26
Embeds 0
No embeds

No notes for slide
  • Speaker tips:We want to solve the asynchronous problem, so let’s first look at something extremely synchronous.Everyone should know IEnumerable<T>… Why synchronous?First, let’s not care about Reset which is a historical thing (notice that iterators even don’t bother to implement it).Look at the words: Get (= beg to get something), Move (= ask for something to happen).C# 4.0 variance indicates how information flows: you have to drag the data out of the source.Implication: you can get stuck (e.g. your favorite SQL Server on the other side of the world is taking a nap).
  • Speaker tips:Summary slide to drive concept home:Use comparison with enumerable interfaces here!Instead of begging for an enumerator, you now give the source an observer…Data flow is reversed:A value of type T is given to you……reflected as input and hence contravariance in C# 4.0Implication:Getting stuck in enumerators means getting too little……which is dual to getting too much or getting flooded for observers!Can compare to subscribing to a news paperWhen calling subscribe:You give the address of your letter box (the observer)You get a way to undo the subscription in the future (the IDisposable is like a letter to cancel the subscription)Asynchronous nature! You’re not blocked till the next news paper arrives.The observer is the letter box:OnNext happens when the postman drops the newsletter in itOnError happens when someone bombs your letter box or the postman drops deadOnCompleted happens when the newspaper publisher goes bankrupt
  • Speaker tips:The essential difference is who controls how the data is received.Philosophically this is nothing but how the application and the environment work together.Looking from the application’s point of view:Does it ask the environment – interactively – for data?  enumerableDoes it passively wait for the environment to send data and react to it?  observableBoth are complementary models. One doesn’t (aim to) replace the other.Matter of which one aligns more closely to which model:SQL’ s TDS protocol is pull-based, hence IE<T> is the best fit.Stock broker services may be push-based, hence IO<T> is a better match.Will see how one can convert between those.
  • Speaker tips:Ask the audience about the pain of asynchronous method patternsWonder about any of the clouds that will pop up later…Same problems as with eventsHave to see the EndXXX signature to see the result type of the operationIn fact, for the sample, even the byte[] is not the real result (EndRead returns the number of bytes read…)Passing such a “pattern” around is hardReally need to pass two methods, maybe a Tuple<T1,T2> with two Func delegates? AarrghSame problem as with the GPS sensor sample – can’t abstract over itEmphasize interfaces help to save the mission – IObservable<T> can abstract over events, asynchronous methods, etc…Composition again lacksEveryone has to write code in the callback to do common operationsCode runs off the screen due to the continuous indentation (especially when trying to compose with another asynchronous call inside the callback of the first one!)
  • Speaker tips”FromAsyncPattern just like FromEventGive us what you’d be doing otherwiseHere we need two delegatesSignature requires some explanationFirst inputs (as on BeginXXX method), then output (comes from EndXXX method)Result is a function that takes the BeginXXX inputs……but returns an IObservable around the resultNow we can do composition (refer to later)
  • Speaker tips:Time to connect up the textbox to the listbox, using the web serviceUse types something  after projection really a sequence of string valuesNow we want to compose this with a web service callAnd stay asynchronous throughout the entire composition!!!Notice we’ll want to reduce the number of calls triggered by the userAssume every call costs money ($$$ on arrow)What if the user types fast?What if the user enters duplicates?Will see how to tackle those concerns in the demo…After composition we should get an observable with wordsBut can throw an error too!!!Finally we do data binding on the UI thread ObserveOn as we saw before (messages will come to us from the background thread of the service callback)
  • Speaker tips:How to do composition?Skip over the input code quicklyWe’ll talk about this in the demoHint at DistinctUntilChanged and Throttle (recall the $$$ aspect from previous slide)Recall how we bridged with the web service, no surprises hereNote: slightly simplified code here (see HOL), e.g. “wn” and “prefix” are omittedWhat matters is SelectManyHow would you query suppliers across different products?Recall Northwind scheme in SQL…Use of two from clauses  is some kind of join reallyEffect shows how C# translates this syntax in a call to SelectMany
  • Speaker tips:How to do composition?Skip over the input code quicklyWe’ll talk about this in the demoHint at DistinctUntilChanged and Throttle (recall the $$$ aspect from previous slide)Recall how we bridged with the web service, no surprises hereNote: slightly simplified code here (see HOL), e.g. “wn” and “prefix” are omittedWhat matters is SelectManyHow would you query suppliers across different products?Recall Northwind scheme in SQL…Use of two from clauses  is some kind of join reallyEffect shows how C# translates this syntax in a call to SelectMany
  • Speaker tips:How to do composition?Skip over the input code quicklyWe’ll talk about this in the demoHint at DistinctUntilChanged and Throttle (recall the $$$ aspect from previous slide)Recall how we bridged with the web service, no surprises hereNote: slightly simplified code here (see HOL), e.g. “wn” and “prefix” are omittedWhat matters is SelectManyHow would you query suppliers across different products?Recall Northwind scheme in SQL…Use of two from clauses  is some kind of join reallyEffect shows how C# translates this syntax in a call to SelectMany
  • Reactive Programming

    1. 1. Reactive Programming @maruyama097 丸山不二夫
    2. 2. In a recent post on the NetBeans developer site, one of the core maintainer observed that a single class had been patched over 14 times to fix threading related problems. --- Brian Goetz et al “Java Concurrency In Practice”
    3. 3. 1/3 of the code in Adobe’s desktop applications is devoted to event handling logic 1/2 of the bugs reported during a product cycle exist in this code --- quoted in Martin Odersky’s “Deprecating the Observer Pattern”
    4. 4. Merriam-Webster defines reactive as “readily responsive to a stimulus”, i.e. its components are “active” and always ready to receive events. This definition captures the essence of reactive applications, focusing on systems that: event-driven, scalable, resilient, responsive --- “Reactive Manifesto”
    5. 5. はじめに  Reactive プログラミングの歴史は、インタラ クティブなUIの登場とともに古い。表計算ソ フトは、もっとも身近な最も成功した Reactive プログラミングの一つである。  現代のReactive プログラミングをドライブし ている力の一つは、ResponsiveなUIへの欲 求である。その主要な舞台は、Web UIであ る。Web Componentとともに、post HTML5の中心的なWeb技術の一つである、 Model Driven View(MDV)は、こうした Reactive プログラミング技術と見ることが出
    6. 6. はじめに  現代のReactive プログラミングをドライブし ているもう一つの力は、非同期でイベント・ ドリブンな処理への志向である。この方向は 、CPUのメニコア化と分散処理の巨大なクラ ウドへの拡大という、まったく異なる二つの 分野でともに強力に押し進められている。  2010年頃に公開されたマイクロソフト社の Rx(Reactive Extention)は、Observableの 役割に注目し、Reactive プログラミングの新 しい手法を切り開いた画期的なものであった 。
    7. 7. はじめに  Rxは、オープンソース化され、多くの言語に 移植され、また多くのReactive プログラミン グ言語に大きな影響を与えた。  Rxの応用で注目すべき事例は、Netflixによる RxのJavaへの移植と、それに基づくAPIの書 き換え・システムの再構築の成功である。  それはまた、小さな関数から大きな関数を合 成するという関数型のアプローチの、大規模 な実システムでの有効性を示すものでもあっ た。
    8. 8. Agenda Part I  WebとReactiveプログラミング       非同期とイベント・ドリブンへの志向 Web UIとReactiveプログラミング Meteor AngularJS Dart Polymer.dart
    9. 9. Agenda Part II  Reactive Extensionの基礎       LINQとEnumerable RxとObservable Observableを使ったEvent処理 Rx for JavaScript Observableを使った非同期処理 AndroidとRx
    10. 10. Agenda Part III  Observableを活用する  Observableのストリームを処理する  Observableを変形・加工する合成可能な 関数  ServerサイドでのRxの事例 Netflix  NetflixでのObservableの利用
    11. 11. Agenda Part IV  Reactive Manifesto  The Need to Go Reactive       Reactive Applications Event-driven Scalable Resilient Responsive Cocclusion
    12. 12. Part I WebとReactiveプログラミン グ
    13. 13. 表計算とReactive Web UI
    14. 14. 表計算ソフトはReactive 最も身近で、成功したアプリの一つ
    15. 15. 表計算のアルゴリズムを考える Loop { セルCijへの入力/修正のイベント検出 Loop { セルCijへの入力/修正は終了したか? } セルCijに関連付けられている全てのマクロMnの検索 Loop { 新しいセルCijの値で全てのMnを再計算 } } Mnが定義されているセルCklの値を再表示
    16. 16. AngularJSの処理
    17. 17. AngularJSの処理 1. 2. 3. 4. 5. 6. 7. ‗X‘ keyが押されると、ブラウザーはinputコントロールに keydownイベントを発する。 input directiveは、inputの値の変化を捉えて、Angular 実行 コンテキスト内のアプリケーション・モデルを変更する為に、 $apply(―name = ‗X‘;‖) を呼び出す。 Angularは、 name = ‗X‘; をモデルに適用する。 $digest ループが始まる。 $watch リストは、name属性の変化を検出すると、 {{name}}補完に通知をして、それが、つづいてDOMを更新す る。 Angularは実行コンテキストを抜け出す。それで、keydownイ ベントは終わり、それとともにJavaScriptの実行コンテキスト も終わる。 ブラウザーは、更新されたテキストで、ビューを再描画する。
    18. 18. 非同期とイベント・ドリブンへ の注目
    19. 19. 2009年11月 JSConf Ryan Dahlの登場  ここでは、node.jsの爆発的な拡大の起点となっ た、2009年ベルリンで行われた、JSConfでの node.jsの創始者Ryan Dahlの講演の一部を見て みよう。 “Node.js, Evented I/O for V8 Javascript” by Ryan Dahl  http://jsconf.eu/2009/speaker/speakers_selecte d.html#entry-3356  http://s3.amazonaws.com/four.livejournal/2009 1117/jsconf.pdf
    20. 20. I/O は、違ったやり方で 行われる必要がある。  多くのWebアプリは、次のようなコードを使 う。 var result = db.query("select * from T"); // use result  データベースを検索している間、ソフトウェ アは何をしているのだろう? たいていの場 合、ただレスポンスを待っているだけである 。  それに加えて、IOによる遅延は、コンピュー タの能力と比較すると、次のように、巨大な http://s3.amazonaws.com/four.livejournal/20091117/jsconf.pdf ものである。
    21. 21. I/O による遅延      L1: 3 cycles L2: 14 cycles RAM: 250 cycles DISK: 41,000,000 cycles NETWORK: 240,000,000 cycles  別の例を挙げよう。サーバーのパフォーマン スも実装によって大きな違いが生まれている 。次のズは、AppacheとNGINXを比較した ものである。
    22. 22. ―Latency as an Effect‖ ―Principles of Reactive Programming‖ Coursera lecture by Erik Meijer https://class.coursera.org/reactive001/lecture/51
    23. 23. 2013 Nov 4th ―Principles of Reactive Programming‖ https://www.coursera.org/course/reactive
    24. 24. trait Socket { def readFromMemory(): Array[Byte] def sendToEurope(packet: Array[Byte]): Array[Byte] } val socket = Socket() val packet = socket.readFromMemory() val confirmation = socket.sendToEurope(packet)
    25. 25. PCでの処理時間
    26. 26. シーケンシャルな実行時間 val socket = Socket() val packet = socket.readFromMemory() // 50,000 ナノ秒ブロックする // 例外が発生しない時には、次の処理へ val confirmation = socket.sendToEurope(packet) // 150,000,000 ナノ秒ブロックする // 例外が発生しない時には、次の処理へ
    27. 27. 1 ナノ秒を 1 秒だと思うと
    28. 28. 1ナノ秒を1秒だとした場合の実行 時間 val socket = Socket() val packet = socket.readFromMemory() // 3日間ブロックする // 例外が発生しない時には、次の処理へ val confirmation = socket.sendToEurope(packet) // 5年間ブロックする // 例外が発生しない時には、次の処理へ
    29. 29. var result = db.query("select..");  このようなコードは、全体のプロセスをブロ ックするか、複数のプロセスの実行をスタッ クさせることになるかのいずれかである。  しかし、次のようなコードでは、プログラム は、すぐにevent loopに戻ることが可能であ る。どのようなメカニズムも必要としない。 db.query("select..", function (result) { // use result });  これが、I/Oが行われるべき方法である。  では、何故、誰もがevent loopやCallbackや Non-BlokingI/Oを使わないのだろうか?
    30. 30. 文化的偏見  我々は、I/Oを次のように行うと教えられてき た puts("Enter your name: "); var name = gets(); puts("Name: " + name);  我々は、入力を要求されたら、それが終わる まで何もしないと教えられてきた。次のよう なコードは、複雑すぎるとして、退けられて きた。 puts("Enter your name: "); gets(function (name) {
    31. 31. インフラの不在  それでは、何故、誰もが event loopを使わな いのだろう?  シングル・スレッドのevent loopは、I/Oが non-blockingであることを要求するのだが、 ほとんどのライブラリーはそうなっていない 。  POSIX async file I/O は使えない.  Man pagesは、関数がディスクにアクセスするこ とがあることを触れていない。 (e.g getpwuid())  Cに、クロージャーや無名関数がないことが、コ ールバックを難しくしている。
    32. 32. JavaScript  Javascriptは、event loopと一緒に使われる ように、特別にデザインされた言語である。  無名関数、クロージャー  同時には、一つだけのコールバック  DOMのイベントコールバックを通じたI/O  JavaScriptのカルチャーは、既に、イベント 中心のプログラミングの準備ができている。
    33. 33. node.js project: 高度な並列プログラムを記述する、純 粋にイベント中心で、non-blocking なインフラを提供すること。
    34. 34. Libuv  libuv enforces an asynchronous, eventdriven style of programming.  Its core job is to provide an event loop and callback based notifications of I/O and other activities.  libuv offers core utilities like timers, non-blocking networking support, asynchronous file system access, child processes and more.
    35. 35. ―Brief Hisory of Node.js‖ Ben Noordhuis http://vimeo.com/51637038
    36. 36. ―An Introduction to libuv‖ Nikhil Marathe November 10, 2013 Release 1.0.0 http://nikhilm.github.io/uvbook/An% 20Introduction%20to%20libuv.pdf
    37. 37. #include #include #include #include <stdio.h> <fcntl.h> <unistd.h> <uv.h> libuvスタイルでの catの実装 void on_read(uv_fs_t *req); uv_fs_t open_req; uv_fs_t read_req; uv_fs_t write_req; char buffer[1024]; イベントの ようなもの open, red, writeの libuv版は、第一引数に loopを取る。最終引数は callback void on_write(uv_fs_t *req) { // callbackのsigniture uv_fs_req_cleanup(req); if (req->result < 0) { fprintf(stderr, "Write error: %sn", uv_strerror(uv_last_error(uv_default_loop()))); } else { uv_fs_read(uv_default_loop(), &read_req, open_req.result, buffer, sizeof(buffer), -1, on_read); // callback } } // on_write callbackの中で、on_read callbackが呼ばれる
    38. 38. void on_read(uv_fs_t *req) { // callbackのsigniture uv_fs_req_cleanup(req); if (req->result < 0) { fprintf(stderr, "Read error: %sn", uv_strerror(uv_last_error(uv_default_loop()))); } else if (req->result == 0) { uv_fs_t close_req; // synchronous uv_fs_close(uv_default_loop(), &close_req, open_req.result, NULL); } // callbackがNULL、同期型 else { uv_fs_write(uv_default_loop(), &write_req, 1, buffer, req->result, 1, on_write); } // callback } // on_read callbackの中で、on_write callbackが呼ばれる
    39. 39. void on_open(uv_fs_t *req) { // callbackのsigniture if (req->result != -1) { uv_fs_read(uv_default_loop(), &read_req, req->result, buffer, sizeof(buffer), -1, on_read); // callback } else { fprintf(stderr, "error opening file: %dn", req->errorno); } uv_fs_req_cleanup(req); } // on_open callbackの中で、on_read callbackが呼ばれる int main(int argc, char **argv) { uv_fs_open(uv_default_loop(), &open_req, argv[1], O_RDONLY, 0, on_open); // callback return 0; } // openは、on_open callbackを呼んで、すぐループに入る。
    40. 40. Callback Hell  “A guide to writing asynchronous javascript programs” http://callbackhell.com/ Asynchronous javascript, or javascript that uses callbacks, is hard to get right intuitively.  “Callback hell in nodejs?” http://stackoverflow.com/questions/18095107/callbackhell-in-nodejs In below code am I in callbackhell? How to overcome such scenario without using any async modules in pure javascript?
    41. 41. Web UIとReactiveプログラミ ング
    42. 42. Web UI での Reactive / Model Driven View(MDV)への志向  Meteor.js  Reactive プログラミング  Reactive-contextとReactive-data-source  publish/subscribe モデル  AngularJS  Imperativeからdeclarative  Data binding  Polymer.js  Model Driven View  .....
    43. 43. Meteor Reactive プログラミング http://docs.meteor.com/ https://github.com/meteor/meteor
    44. 44. Meteor Template <template name="hello"> <div class="greeting">Hello there, {{first}} {{last}}!</div> </template> // in the JavaScript console > Template.hello({first: "Alyssa", last: "Hacker"}); => "<div class="greeting">Hello there, Alyssa Hacker!</div>" Meteor.render(function () { return Template.hello({first: "Alyssa", last: "Hacker"}); }) => automatically updating DOM elements
    45. 45. Meteor LiveHTML var fragment = Meteor.render( function () { var name = Session.get("name") || "Anonymous"; return "<div>Hello, " + name + "</div>"; }); document.body.appendChild(fragment); Session.set(“name”, “Bob”); // ページは自動的に更新される
    46. 46. Meteor.render()  Meteor.render は、rendering function、ある HTMLを文字列として返すを関数を引数に取る。それ は、自動更新するDocumentFragmentを返す。  rendering functionで利用されたデータに変更があ ったとき、それは、再実行される。 DocumentFragment内のDOMノードは、ページの どの場所に挿入されていても、その場で自分自身を更 新する。それは全く自動的である。  Meteor.renderは、rendering functionによって、 どのデータが利用されたかを発見する為にreactive contextを使う。
    47. 47. Meteor: reactive context + reactive data source  reactive context + reactive data source という 単純なパターンは、広い応用可能性をもっている。  それ以上に、プログラマーは、 unsubscribe/resubscribe の呼び出しのコードを書 く手間が省け、それらは、正しい時に確実に呼び出さ れことになる  一般的に、Meteorは、そうでなければ、誤りを犯し やすいロジックで、アプリケーションの邪魔になる、 データ伝搬の全てのクラスを取り除くことが出来る、
    48. 48. AngularJS Data Binding http://angularjs.org/ https://github.com/angular/angular.j s
    49. 49. AngularJS Data Binding デモ <!doctype html> <html ng-app> <head> <script src= "http://code.angularjs.org/1.2.0rc1/angular.min.js"> </script> </head> <body> <input ng-model="name"> <p>Hello {{name}}!</p> </body> </html>
    50. 50. Controller  controllerは、viewの背後にあるコードで ある。その役割は、モデルを構築して、コー ルバック・メソッドにそって、それをビュー に公開することである。  viewは、scopeのtemplate(HTML)上へ の投射である。  scopeは、モデルをviewにつなげ、イベント をControllerに向けさせる「つなぎ」の役割 を果たす。
    51. 51. The separation of the controller and the view  controllerは、JavaScriptで書かれる。 JavaScript は命令型である。命令型は、アプリケーションの振る 舞いを指定するには、もっとも適している。 controllerは、(DOMへの参照、HTMLの断片のよう な)レンダー用の情報を含むべきではない。  view templateはHTMLで書かれる。HTMLは宣言型 である。宣言型は、UIの指定に最適である。viewは 、振る舞いを含むべきではない。  controllerはviewのことを知らないので、同一の contorollerに対して複数のviewがあり得る。このこ とは、スキンの変更・デバイス特有のview(モバイ ルとPC)・テスト可能性に取って、重要である。
    52. 52. Model  modelは、templateとマージされてviewを生み出す データである。modelがviewにレンダーされる為に は、modelは、scopeから参照されなければならない 。  他の多くのフレームワークとは異なって、Angularは 、modelについて何の制限も要請も設けてはいない。 modelにアクセス、あるいはmodelを変更する為に 、継承すべきクラスも、特別のアクセス・メソッドも ない。  modelは、プリミティブでも、オブジェクト・ハッシ ュでも、全くのオブジェクト型でも構わない。要する に、modelは、‖plain JavaScript object‖ なのであ る。
    53. 53. View  viewは、ユーザーが見るものである。viewの ライフサイクルは、templateとして始まる。 viewは、modelとマージされて、最終的には 、ブラウザーのDOMにレンダーされる。  Angularは、他の大部分のtemplateシステム と比較して、全く異なるアプローチを採用し ている。  Angularのtemplateシステムは、文字列の上 ではなくDOMオブジェクトの上で動く。 templateは確かにHTMLで書かれているが、 それはHTMLである。
    54. 54. MDV templates in Dart https://www.dartlang.org/articles/we b-ui/#one-way-binding
    55. 55. MDV templates in Dart  One-way data binding: Embed data into your UI  Two-way data binding: Keep data in sync with UI changes  Conditionals: Selectively show parts of the UI  Loops: Construct lists and tables by iterating over collections  Event listeners: Easily attach code that reacts to UI events
    56. 56. One-way data binding <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <link rel="stylesheet‖ href="//cdnjs.cloudflare.com/ajax/libs /twitter-bootstrap/2.3.1/css/bootstrap.css"> </head> <body> <div class="well">Hello {{dataValue}}!</div> <script type="application/dart"> String dataValue; main() { var today = new DateTime.now(); dataValue = 'world ${today.year}-${today.month}-${today.day}'; } </script> </body> </html>
    57. 57. <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <link rel="stylesheet ‖href="//cdnjs.cloudflare.com/ajax/libs /twitter-bootstrap/2.3.1/css/bootstrap.css"> </head> <body> <div class="well">Hello counter: {{count}}</div> <script type="application/dart"> import 'dart:async' as async; import 'dart:html' as html; import 'package:web_ui/watcher.dart' as watchers; int count; main() { count = 0; new async.Timer.periodic(const Duration(seconds: 1), (_) { count++; watchers.dispatch(); }); } </script> </body> </html>
    58. 58. Two-way data binding <html lang="en"> <head> ..... </head> <body> <div class="well"> Input: <input type="text" bind-value="str" placeholder="type something here"> <div> Value: {{str}}</div> <div> Length: {{str.length}}</div> </div> <script type="application/dart"> String str = ''; main() {} </script> </body> </html>
    59. 59. Conditionals <html lang="en"> <head> ..... </head> <body> <div class="well"> <div> Input1: <input type="text" bind-value="str1"></div> <div> Input2: <input type="text" bind-value="str2"></div> <template if='str1 == str2'> <div>They match!</div> </template> </div> <script type="application/dart"> String str1 = ''; String str2 = ''; main() {} </script> </body> </html>
    60. 60. <html lang="en"> <head> ..... </head> <body> <input type="checkbox" bind-checked="show">Show phones <br> <table class="table"> <thead> <tr> <td>Last</td><td>First</td> <td template if="show">Phone</td> </tr> </thead> <tbody> <tr> <td>Bracha</td> <td>Gilad</td> <td template if="show">555-555-5555</td> </tr>
    61. 61. <tr> <td>Bak</td> <td>Lars</td> <td template if="show">222-222-2222</td> </tr> <tr> <td>Ladd</td> <td>Seth</td> <td template if="show">111-222-3333</td> </tr> </tbody></table> <script type="application/dart"> bool show = true; main() {} </script> </body> </html>
    62. 62. Loops <html lang="en"> <head> ..... </head> <body> <table class="table"> <tbody template iterate='row in table'> <tr template iterate='cell in row'> <td>{{cell}}</td> </tr> </tbody> </table> <script type="application/dart"> var table = [['X', 'O', '_'], ['O', 'X', '_'], ['_', '_', 'X']]; main() {} </script> </body> </html>
    63. 63. Event listeners <html lang="en"> <head> ..... </head> <body> <div class="well"> <button on-click="increment()">Click me</button> <span>(click count: {{count}})</span> </div> <script type="application/dart"> int count = 0; void increment() { count++; } main() {} </script> </body> </html>
    64. 64. Polymer.dart Observables and Data Binding with Web UI https://www.dartlang.org/webui/observables/
    65. 65. Overview of data binding in Web UI  Web UI helps you efficiently bind application data to HTML, and vice versa, with observables and observers.  Observables are variables, fields, or collections that can be observed for changes.  Observers are functions that run when an observable changes.
    66. 66. Efficiently tracking changes  Instead of asking every possible observable ―Did you change?‖ on every event loop over and over, Web UI has an efficient mechanism to notify only the right observers at the right time.
    67. 67. Observing variables <body> <h1>Hello Web UI</h1> <p>Web UI is {{ superlative }}</p> <button id="change-it" on-click="changeIt()"> Change</button> <script type="text/javascript" src="dart.js‖> </script> <script type="application/dart" src="hello_world.dart"> </script> </body>
    68. 68. library hello_world; import 'package:web_ui/web_ui.dart'; @observable String superlative = 'awesome'; const List<String> alternatives = const <String>['wicked cool', 'sweet', 'fantastic', 'wonderful']; int _alternativeCount = 0; String get nextAlternative => alternatives[_alternativeCount++ % alternatives.length]; changeIt() { superlative = nextAlternative; } main() { }
    69. 69. Observing classes <p>Hello {{person.name}}!</p> <p><button on-click="newName()"> Change Name</button></p> @observable class Person { String name; Person(this.name); } final Person person = new Person('Bob'); const List<String> names = const <String> ['Sally', 'Alice', 'Steph']; newName() { person.name = nextName; }
    70. 70. Observing collections final List<DateTime> timestamps = toObservable([]); void addTimestamp() { timestamps.add(new DateTime.now()); } void clear() { timestamps.clear(); }
    71. 71. Observing nested objects @observable class Person { String name; Address address; } @observable class Address { String city; } @observable Person person; main() { person = new Person() ..name = 'Clark Kent' ..address = ( new Address() ..city = 'Metropolis' ); }
    72. 72. Expression Observers <p>The time is <span id="msg"></span></p> <p><button on-click="updateMsg()"> Update</button></p> @observable String msg; updateMsg() { msg = new DateTime.now().toString(); } main() { observe(() => msg, (_) { query('#msg').text = msg; }); }
    73. 73. Part II Reactive Extensionの基礎
    74. 74. Reactive Extension (Rx) by Microsoft http://msdn.microsoft.com/enus/data/gg577609.aspx
    75. 75. Reactive Extensionとは?  ―The Reactive Extensions (Rx) is a library to compose asynchronous and event-based programs using observable collections and LINQ-style query operators.‖  「Reactive Extensionは、非同期かつイベン ト・ベースのプログラムをオブザーバブル・ コレクションとLINQスタイルの検索操作を利 用して構成する為のライブラリーである。」
    76. 76. 講演資料  2010年 11月 DevCamp Keynote ―Rx: Curing your asynchronous programming blues‖ http://channel9.msdn.com/Blogs/codefest/DC2010T010 0-Keynote-Rx-curing-your-asynchronous-programmingblues  2012年 6月 TechEd Europe ―Rx: Curing your asynchronous programming blues‖ http://channel9.msdn.com/Events/TechEd/Europe/2012/ DEV413
    77. 77. Rx オープンソース化と移植  2012年11月 MS Open Tech からオープンソ ースとして公開。 Rx.NET :https://github.com/ReactiveExtensions/Rx.NET  あわせて、JavaScript、C++、Python、Ruby への移植版もオープンソースとして公開。     RxJS : https://github.com/Reactive-Extensions/RxJS RxCpp :https://github.com/Reactive-Extensions/RxCpp RxPy : https://github.com/Reactive-Extensions/RxPy Rx.rb : https://github.com/Reactive-Extensions/Rx.rb
    78. 78. RxJava  Netflixは、Rx.NETをJavaに移植し、オープ ンソースとして公開した。 RxJava: https://github.com/Netflix/RxJava/  Netflixは、自社のシステムをRxJavaを用い て書き換え、大規模システムでのReactive プ ログラミングの有効性を示した。  2013年2月 ―Functional Reactive in the Netflix API with RxJava‖ http://techblog.netflix.com/2013/02/rxjavanetflix-api.html
    79. 79. RxJavaの移植によって、JVM上で走る、Clojure, Scala, Groovy, Jruby等の言語でもReactive Extension が走るようになった。
    80. 80. LINQとEnumerable データソースの抽象化として、.NET 3.0 から導入されたLINQで、中心的な役割を 果たすのは、Enumerableインターフェー スである。 http://code.msdn.microsoft.com/101-LINQSamples-3fb9811b
    81. 81. LINQの最も重要なインターフェース Enumerable 全てのCollectionクラスは、IEnumerableを実装している interface IEnumerable<out T> { IEnumerator<T> Enumerator(); } interface IEnumerator<out T> : IDisposable { bool Next(); T Current { get; } void Reset(); }
    82. 82. LINQで利用出来るオペレータ Projection: Select, SelectMany Restriction: Where Partitioning: Take, Skip, TakeWhile, ... Ordering: OrderBy, OrderByDecsending, ... Grouping: GroupBy Set: Distinct, Union, Intersect, .. Conversion: ToList, ToArray, .. Generation: Range, Repeat Aggregate: Count, Sum, Min, Max, Average, ....
    83. 83. LINQは、SQLライクな検索構文で、データソースから データソースを導出することが出来る public void Linq1() { int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; var lowNums = from n in numbers where n < 5 select n; } Console.WriteLine("Numbers < 5:"); foreach (var x in lowNums) { Console.WriteLine(x); }
    84. 84. LINQでは、検索式の中にラムダ式を利用出来る public void Linq5() { string[] digits = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" }; var shortDigits = digits.Where( (digit, index) => digit.Length < index); } Console.WriteLine("Short digits:"); foreach (var d in shortDigits) { Console.WriteLine( "The word {0} is shorter than its value.", d); }
    85. 85. SelectMany (多段のSelect) public void Linq14() { int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 }; int[] numbersB = { 1, 3, 5, 7, 8 }; var pairs = from a in numbersA from b in numbersB where a < b select new { a, b }; } Console.WriteLine("Pairs where a < b:"); foreach (var pair in pairs) { Console.WriteLine( "{0} is less than {1}", pair.a, pair.b); }
    86. 86. SelectMany (多段のSelect) public void Linq15() { List<Customer> customers = GetCustomerList(); var orders = from c in customers from o in c.Orders where o.Total < 500.00M select new { c.CustomerID, o.OrderID, o.Total }; } ObjectDumper.Write(orders);
    87. 87. SelectMany (多段のSelect) public void Linq18() { List<Customer> customers = GetCustomerList(); DateTime cutoffDate = new DateTime(1997, 1, 1); var orders = from c in customers where c.Region == "WA" from o in c.Orders where o.OrderDate >= cutoffDate select new { c.CustomerID, o.OrderID };
    88. 88. public void Linq41() { string[] words = { "blueberry", "chimpanzee", "abacus", "banana", "apple", "cheese" }; var wordGroups = from w in words group w by w[0] into g select new { FirstLetter = g.Key, Words = g }; } foreach (var g in wordGroups) { Console.WriteLine( "Words that start with the letter '{0}':", g.FirstLetter); foreach (var w in g.Words) Words that start with the letter 'b': blueberry { banana Console.WriteLine(w); Words that start with the letter 'c': chimpanzee } cheese } Words that start with the letter 'a': abacus apple
    89. 89. Reactive Extensionと Observable Rxで中心的な役割を果たすのは、イベン トのソースを抽象化したObservableであ る。それは、データソースの抽象化として 、LINQで中心的な役割を果たす Enumerableとよく似ている。
    90. 90. ObservableとObserver  Observableは、Enumerableと同様に、デー タの集まり。それは相互に変換可能。  Observableには時間の概念が入っている。 それは時間とともにデータを生み出す。イベ ントの抽象に用いられる時に便利である。  データ・ソースとしてのObservableが生成す るデータは、ObservableにObserverが Subscribeした時に、はじめて利用出来る。  データはObservableからSubscribeの時に指 定したObserver上の関数に自動的に送り出さ れる。(Push)
    91. 91. Observer上の三つの関数 OnNext, OnError, OnComplete  ObservableからObserverへデータがpushさ れる時に、次の三つの関数のみが利用される 。  OnNext(): 通常のデータの受け渡し。  OnError(): エラーが発生したこと伝える。  OnComplete(): 送るべきデータが終了したこ とを伝える。  これらの関数の定義は、Observableへの Subscribeの際に与えられねばならない。  ObservableへのSubscribeは、 Subscriptionを返す。この値は、Sunscribe
    92. 92. EnumarableとObservable Enumerable どちらもデータの集りである Observable 時間の流れ
    93. 93. EnumerableとObservableは、 相互に変換出来る Enumerable  Observable .ToObservable(); Observable  Enumerable .ToEnumerable()
    94. 94. Rxの最も重要なインターフェース Observable interface IObservable<out T> { IDisposable Subscribe(IObserver<T> observer); } interface IObserver<in T> { void OnNext(T value); void OnError(Exception ex); void OnCompleted(); } Observerが 実装する3つの タイプのメソッド
    95. 95. ObservableからObserverへの通知 OnNext (42) OnNext (43) OnNext (―Hello‖) OnCompleted OnError (error) OnNext* (OnError | OnCompleted)?
    96. 96. // Range()は、次のようなObservablを生成する // -1-2-3-4-5-6-7-8-9-10-| IObservable<int> source = Observable.Range(1, 10); // ここでは、Subscribe()は、三つの引数を取っている。 // 順番に、OnNext,OnError,OnCompleteの定義である IDisposable subscription = source.Subscribe( Obser x => Console.WriteLine("OnNext: {0}", x), verが ex => Console.WriteLine("OnError: {0}", 実装する ex.Message), 3つの () => Console.WriteLine("OnCompleted") タイプの ); メソッド Console.WriteLine("Press ENTER to unsubscribe..."); Console.ReadLine(); // Subscribeをやめる subscription.Dispose();
    97. 97. internal class Generate_Simple { private static void Main() { var observable = Observable.Generate(1, // 初期値 -1-2-3-4-5-| x => x < 6, // 条件 x => x + 1, // 増分 x => x, // 返り値 x=>TimeSpan.FromSeconds(1)).Timestamp(); // ここでは、SubscribeにはOnNextの定義だけが与えられている using (observable.Subscribe(x => Console.WriteLine( "{0}, {1}", x.Value, x.Timestamp))) { Console.WriteLine("Press any key to unsubscribe"); Console.ReadKey(); } } } Console.WriteLine("Press any key to exit"); Console.ReadKey();
    98. 98. class Select_Simple { static void Main() { // 一秒間隔で数列を生成する var oneNumberPerSecond = Observable. Interval(TimeSpan.FromSeconds(1)); var numbersTimesTwo = // 新しいObservableの生成 from n in oneNumberPerSecond select n * 2; // LINQが使える! } } Console.WriteLine("Numbers * 2:"); numbersTimesTwo.Subscribe(num => { Console.WriteLine(num); } // OnNextの定義が引数で与えられている ); Console.ReadKey();
    99. 99. MoveNex t IEnumerable<T> IEnumerator<T> Environment Have next! IObservable<T> IObserver<T> Reactive Got next? OnNext Interactive Application
    100. 100. Observableを使ったEvent処理
    101. 101. る マウスは、イベントのデータベー ス! var lbl = new Label(); var frm = new Form { Controls = { lbl } }; var moves = Observable. FromEvent<MouseEventArgs>(frm, "MouseMove"); using (moves.Subscribe (evt => { lbl.Text = evt.EventArgs.Location.ToString(); })) { Application.Run(frm); }
    102. 102. var txt = new TextBox(); var frm = new Form { Controls = { txt } }; var moves = Observable.FromEvent<MouseEventArgs> (frm, "MouseMove"); var input = Observable.FromEvent<EventArgs> (txt, "TextChanged"); var movesSubscription = moves.Subscribe( evt => { Console.WriteLine("Mouse at: " + evt.EventArgs.Location); }); var inputSubscription = input.Subscribe( evt => { Console.WriteLine("User wrote: " + ((TextBox)evt.Sender).Text); }); using (new CompositeDisposable( movesSubscription, inputSubscription)) { Application.Run(frm); }
    103. 103. var moves = from evt in Observable. FromEvent<MouseEventArgs>(frm, "MouseMove") select evt.EventArgs.Location; var input = from evt in Observable. FromEvent<EventArgs>(txt, "TextChanged") select ((TextBox)evt.Sender).Text; var movesSubscription = moves.Subscribe( pos => Console.WriteLine("Mouse at: " + pos)); var inputSubscription = input.Subscribe( inp => Console.WriteLine("User wrote: " + inp)); var overFirstBisector = from pos in moves where pos.X == pos.Y select pos; var movesSubscription = overFirstBisector.Subscribe( pos => Console.WriteLine("Mouse at: " + pos));
    104. 104. 違った値が来た時のみデータを送る var input = (from evt in Observable.FromEvent<EventArgs>(txt, "TextChanged") select ((TextBox)evt.Sender).Text) .DistinctUntilChanged(); Doは、Observablを変化させずに、OnNextを実行する var input = (from evt in Observable.FromEvent<EventArgs>(txt, "TextChanged") select ((TextBox)evt.Sender).Text) .Do(inp => Console.WriteLine("Before DistinctUntilChanged: " + inp)) .DistinctUntilChanged(); Throttleは指定された時間の間、Observableのイベントを抑制する TimeSpan.FromSecond(1)は、一秒間の指定 var input = (from evt in Observable.FromEvent<EventArgs>(txt, "TextChanged") select ((TextBox)evt.Sender).Text) .Throttle(TimeSpan.FromSeconds(1)) .DistinctUntilChanged(); using (input.ObserveOn(lbl).Subscribe(inp => lbl.Text = inp)) Application.Run(frm);
    105. 105. Reactive Extension for JavaScript
    106. 106. var source = null; // Observableとしてsourceを生成するコード(省略) var subscription = source.Subscribe( // 三つの関数の定義が順番に引数に与えられている function (next) { $("<p/>").html("OnNext: " + next) .appendTo("#content"); }, function (exn) { $("<p/>").html("OnError: " + exn) .appendTo("#content"); }, function () { $("<p/>").html("OnCompleted") .appendTo("#content"); } );
    107. 107. var source = Rx.Observable.Empty(); OnCompleted var source = Rx.Observable.Throw("Oops!"); OnError: Oops var source = Rx.Observable.Return(42); OnNext: 42 OnCompleted var source = Rx.Observable.Range(5,3); OnNext: 5 OnNext: 6 OnNext: 7 OnCompleted
    108. 108. var source = Rx.Observable.Generate( 0, function (i) { return i < 4; }, function (i) { return i + 1; }, // Like a for loop function (i) { return i * i; } ); OnNext: 0 OnNext: 1 OnNext: 4 OnNext: 9 OnCompleted
    109. 109. RxJS: DOMイベントをObservableに
    110. 110. $(document).ready(function () { $(document).mousemove(function (event) { // A position tracking mechanism, // updating a paragraph called ―content‖ $("<p/>") .text("X: " + event.pageX + " Y: " + event.pageY) .appendTo("#content"); }); jQuery }); RxJS $(document).ready(function () { $(document).toObservable("mousemove") .Subscribe(function (event) { // A position tracking mechanism, // updating a paragraph called ―content‖ $("<p/>") .text("X: " + event.pageX + " Y: " + event.pageY) .appendTo("#content"); }); });
    111. 111. $(document).ready(function () { $(document).toObservable("mousemove") .Subscribe(function (event) { $("<p/>") .text("X: " + event.pageX + " Y: " + event.pageY) .appendTo("#content"); }); $("#textbox").toObservable("keyup") .Subscribe(function (event) { $("<p/>") .text("User wrote: " + $(event.target).val()) .appendTo("#content"); }); });
    112. 112. var moves = $(document).toObservable("mousemove") .Select(function(event) { return { pageX : event.pageX, pageY : event.pageY }; }); var inputs = $(―#textbox‖).toObservable(‖keyup‖) .Select(function(event) { return $(event.target).val(); });
    113. 113. var movesSubscription = moves.Subscribe( function (pos) { $("<p/>‖) .text("X: " + pos.pageX + " Y: " + pos.pageY) .appendTo("#content"); }); var inputSubscription = input.Subscribe( function (text) { $("<p/>") .text("User wrote: " +text) .appendTo("#content"); });
    114. 114. var overFirstBisector = moves .Where(function(pos) { return pos.pageX === pos.pageY; }); var movesSubscription = overFirstBisector .Subscribe(function (pos) { $("<p/>") .text("Mouse at: "+pos.pageX+","+pos.pageY) .appendTo("#content"); });
    115. 115. var inputs = $(―#textbox‖).toObservable(‖keyup‖) .Select(function(event) { return $(event.target).val(); } .DistinctUntilChanged(); ); var inputSubscription = input.Subscribe( function (text) { $("<p/>") .text("User wrote: " +text) .appendTo("#content"); });
    116. 116. var inputs = $(―#textbox‖).toObservable(‖keyup‖) .Select(function(event) { return $(event.target).val(); } .Throttle(1000) .DistinctUntilChanged(); ); var inputSubscription = input.Subscribe( function (text) { $("<p/>") .text("User wrote: " +text) .appendTo("#content"); });
    117. 117. Observableと非同期処理
    118. 118. .NETの非同期プログラミング FileStream fs = File.OpenRead("data.txt"); byte[] bs = new byte[1024]; fs.BeginRead(bs, 0, bs.Length, new AsyncCallback(iar => { int bytesRead = fs.EndRead(iar); // Do something with bs[0..bytesRead-1] }), null );
    119. 119. Rxでの非同期処理 FileStream fs = File.OpenRead("data.txt"); Func<byte[], int, int, IObservable<int>> read = Observable.FromAsyncPattern<byte[], int, int, int>( fs.BeginRead, fs.EndRead); byte[] bs = new byte[1024]; read(bs, 0, bs.Length).Subscribe(bytesRead => { // Do something with bs[0..bytesRead-1] });
    120. 120. 非同期サンプル ネットワーク上のサービスの利用 Asynchronous request React TextChanged Reaction Reactive Reactor Data binding on UI thread Dictionary web service
    121. 121. // IObservable<string> from TextChanged events var changed = Observable.FromEvent<EventArgs>(txt,"TextChanged"); var input = (from text in changed select ((TextBox)text.Sender).Text); .DistinctUntilChanged() .Throttle(TimeSpan.FromSeconds(1)); // Bridge with the dictionary web service var svc = new DictServiceSoapClient(); var lookup = Observable.FromAsyncPattern<string,DictionaryWord[]> (svc.BeginLookup, svc.EndLookup); // Compose both sources using SelectMany var res = from term in input from words in lookup(term) select words;
    122. 122. function searchWikipedia(term) { return $.ajaxAsObservable( { url: "http://en.wikipedia.org/w/api.php", dataType: "jsonp", data: { action: "opensearch", search: term, format: "json" } }) .Select(function (d) { return d.data[1]; }); } var searchObservable = searchWikipedia("react"); var searchSubscription = searchObservable.Subscribe( function (results) { $("#results").empty(); $.each(results, function (_, result) { $("#results").append("<li>" + result + "</li>"); }); }, function (exn) { $("#error").text(error); } );
    123. 123. var searchObservable = terms.SelectMany( function (term) { return searchWikipedia(term); } ); var searchObservable = terms.SelectMany(searchWikipedia); var res = from term in terms from words in searchWikipedia(term) select words;
    124. 124. Functional Reactive Programming on Android With RxJava http://mttkay.github.io/blog/2013/08 /25/functional-reactiveprogramming-on-android-withrxjava/
    125. 125. 現在のAsyncTaskを使った処理 class DownloadTask extends AsyncTask<String, Void, File> { protected File doInBackground(String... args) { final String url = args[0]; try { byte[] fileContent = downloadFile(url); File file = writeToFile(fileContent); return file; } catch (Exception e) { // ??? } } } protected void onPostExecute(File file) { Context context = getContext(); // ??? Toast.makeText(context, "Downloaded: " + file.getAbsolutePath(), Toast.LENGTH_SHORT) .show(); }
    126. 126. private Observable<File> downloadFileObservable() { return Observable.create(new OnSubscribeFunc<File>() { @Override public Subscription onSubscribe( Observer<? super File> fileObserver) { try { byte[] fileContent = downloadFile(); File file = writeToFile(fileContent); fileObserver.onNext(file); fileObserver.onCompleted(); } catch (Exception e) { fileObserver.onError(e); } } } }); return Subscriptions.empty();
    127. 127. class MyFragment extends Fragment implements Observer<File> { private Subscription subscription; @Override protected void onCreate( Bundle savedInstanceState) { subscription = AndroidObservables .fromFragment(this,downloadFileObservable()) .subscribeOn(Schedulers.newThread()) .subscribe(this); } private Observable<File> downloadFileObservable() { /* as above */ } @Override protected void onDestroy() { subscription.unsubscribe(); }
    128. 128. Observable<String> filePathObservable = downloadFileObservable().map(new Func1<File, String>() { @Override public String call(File file) { return file.getAbsolutePath(); } }); // now emits file paths, not `File`s subscription = filePathObservable.subscribe( /* Observer<String> */);
    129. 129. public void onNext(File file) { Toast.makeText(getActivity(), "Downloaded: " + file.getAbsolutePath(), Toast.LENGTH_SHORT) .show(); } public void onCompleted() {} } public void onError(Throwable error) { Toast.makeText(getActivity(), "Download failed: " + error.getMessage(), Toast.LENGTH_SHORT) .show(); }
    130. 130. RxJava on Android with Scala => AWESOME http://pommedeterresautee.blogspot. jp/2013/11/rxjava-on-android-withscala-awesome.html
    131. 131. def getAsyncUrl(urlString: String) :Observable[Option[String]] = Observable { (observer: Observer[Option[String]]) => { val url = new URL(urlString) val urlCon = url.openConnection() urlCon.setConnectTimeout(5000) urlCon.setReadTimeout(5000) val io = Source.fromInputStream( urlCon.getInputStream) val result = Option(io.getLines(). mkString.split("n")(0)) io.close() observer.onNext(result) observer.onCompleted() Subscription() } }
    132. 132. val mUnsubscribe = CompositeSubscription() mUnsubscribe += getAsyncUrl(lastScript) .execAsync.subscribe( _ match { case OnNext(Some(t)) => CInfo(t) case OnNext(None) => CAlert(getString( R.string.connection_error_message, "Server error")) case OnError(e) => CAlert(getString(R.string.connection_ error_message, e.getLocalizedMessage)) } )
    133. 133. Reactive extensions for .NET (Rx .NET) for Windows Phone http://msdn.microsoft.com/enus/library/windowsphone/develop/ff4 31792%28v=vs.105%29.aspx
    134. 134. Part III Observableを活用する
    135. 135. Observableのストリームを 処理する Rx サンプル
    136. 136. Stock Trade Analysis MSFT 27.01 INTC 21.75 MSFT 27.96 ticks from tick in ticks MSFT 31.21 INTC 22.54 INTC 20.98 MSFT 30.73
    137. 137. Stock Trade Analysis MSFT 27.01 INTC 21.75 MSFT 27.96 MSFT 31.21 INTC 22.54 INTC 20.98 MSFT 30.73 ticks 27. 01 27. 96 30. 73 31. 21 MSFT 21. 75 INTC from tick in ticks group tick by tick.Symbol 22. 54 20. 98
    138. 138. Stock Trade Analysis MSFT 27.01 INTC 21.75 MSFT 27.96 MSFT 31.21 INTC 22.54 INTC 20.98 MSFT 30.73 ticks [27.01, 27.96] [27.96, 3 1.21] [31.21, 3 0.73] MSFT [21.75, 22.54] INTC from tick in ticks group tick by tick.Symbol into company from openClose in company.Buffer(2, 1) [22.54, 20.98]
    139. 139. Stock Trade Analysis MSFT INTC MSFT INTC Stock 21.75 MSFT Analysis Trade 27.01 27.96 31.21 22.54 INTC 20.98 MSFT 30.73 ticks 0.0 34 0.0 15 0.1 04 MSFT 0.0 36 INTC 0.0 69 from tick in ticks group tick by tick.Symbol into company from openClose in company.Buffer(2, 1) let diff = (openClose[1] – openClose[0])/openClose[0]
    140. 140. Stock Trade Analysis MSFT 27.01 INTC 21.75 MSFT 27.96 MSFT 31.21 0.0 34 INTC 22.54 INTC 20.98 0.1 04 MSFT 30.73 ticks 0.0 15 MSFT 0.0 36 INTC 0.0 69 from tick in ticks group tick by tick.Symbol into company from openClose in company.Buffer(2, 1) let diff = (openClose[1] – openClose[0])/openClose[0] where diff > 0.1
    141. 141. Stock Trade Analysis MSFT 27.01 INTC 21.75 MSFT 27.96 MSFT 31.21 INTC 22.54 INTC 20.98 MSFT 30.73 ticks res Company = MSFT Increase = 0.104 from tick in ticks group tick by tick.Symbol into company from openClose in company.Buffer(2, 1) let diff = (openClose[1] – openClose[0]) / openClose[0] where diff > 0.1 select new { Company = company.Key, Increase = diff }
    142. 142. Observableを変形・加工する 合成可能な関数を利用する
    143. 143. Composable Functions  Transform: map, flatmap, reduce, Scan ...  Filter: take, skip, sample, takewhile, filter ...  Combine: concat, merge, zip, combinelatest, multicast, publish, cache, refcount ...  Concurrency: observeon, subscribeon  Error Handling: onErrorreturn, onErrorResume ...
    144. 144. map def map[B](f: A⇒B): Observable[B]
    145. 145. filter def filter(p: A⇒Boolean): Observable[A]
    146. 146. merge def merge(Observable[A],Obserbal[A]): Observable[A]
    147. 147. flatmap def flatMap(f: T=>Observable[S]): Observable[S] = { map(f).flatten }
    148. 148. flatmap val xs: Observable[Int] = Observable(3,2,1) val yss: Observable[Observable[Int]] = xs.map(x => Observable.Interval(x seconds) .map(_=>x).take(2)) val zs: Observable[Int] = yss.flatten() xs: Observable[Int] yss: Observable [Observable[Int]]] merge zs: Observable[Int]
    149. 149. concat
    150. 150. val xs: Observable[Int] = Observable(3,2,1) val yss: Observable[Observable[Int]] = xs.map(x => Observable.Interval(x seconds) .map(_=>x).take(2)) val zs: Observable[Int] = yss.concat() xs: Observable[Int] yss: Observable [Observable[Int]]] zs: Observable[Int]
    151. 151. zip
    152. 152. groupBy def groupBy[K](keySelector: T⇒K) : Observable[(K,Observable[T])]
    153. 153. startWith def startWith(ss: T*): Observable[T]
    154. 154. reduce def reduce(f:(T, T) ⇒T): Observable[T]
    155. 155. ServerサイドでのRxの利用 Netflix --- RxJava ―a library for composing asynchronous and event-based programs using observable sequences for the Java VM‖
    156. 156. RxJava Java 8へのRxの移植 Observable.toObservable("one‖,"two‖,"three") .take(2) .subscribe( (arg) -> { System.out.println(arg); } ); https://github.com/Netflix/RxJava
    157. 157. Netflix  Netflixは、北米のインターネットのダウンロ ード・トラフィックの33% を占める。  Netflixの顧客は、一月に10億時間以上、テレ ビを見ている。  APIのトラフィックは、2010年の2000万/一 日から、2013年には 20億/一日に成長した。
    158. 158. 一日の Netflix APIへのリクエスト数
    159. 159.  クライアントのデバイスは、Netflixの二つの 主要なサービスに接続する。第一のサービス は、ビデオの検索やそのコンテンツの紹介に 関係した機能を提供するNetflix APIである。 第二のサービスは、ビデオ・ストリームの再 生サービスである。  ここでは、ビデオの検索・発見にかかわる Netflix APIについて見ていく。
    160. 160. Rxの発見は、システムの Re-Atchitectureから始まった
    161. 161. ネットワーク・トラフィックは、 APIの改良で、劇的に改善した 9つあったネットワークの呼び出しは 1つになり、WANでのネットワーク 遅延は一回だけになった クライアントのロジ ックは、サーバに移 され、20以上の呼び 出しが削除された
    162. 162. 関連情報  Netflix API architecture http://techblog.netflix.com/search/label/api https://speakerdeck.com/benjchristensen/  Re-architecture http://techblog.netflix.com/2013/01/optimiz ing-netflix-api.html  Hystrix https://github.com/Netflix/Hystrix
    163. 163. NetflixでのObservableの利用 Netflixでは、ブロックするAPIを Observableを返す非同期のAPIに作り替え 、ついで、それらのObservableを返すAPI を組み合わせてサービスを構成した。
    164. 164. Observableを作る Observable.create({ observer try { observer.onNext(new ....)) observer.onCompleted(); } catch(Exception e) { observer.onError(e); } }) ‐> Observable<T> create(Func1<Observer<T>, Subscription> func)
    165. 165. def Observable<VideoRating> getRating(userId, videoId) { return Observable.create({ observer ‐> executor.execute(new Runnable() { def void run() { try { VideoRating rating = //.. do network call . observer.onNext(rating) observer.onCompleted(); } catch(Exception e) { observer.onError(e); } } }) Asynchronous Observable }) } with Single Values
    166. 166. def Observable<Video> getVideos() { return Observable.create({ observer ‐> executor.execute(new Runnable() { def void run() { try { for ( id in videoIds ) { Video v = // .. do network call ... observer.onNext(v) } observer.onCompleted(); } catch(Exception e) { observer.onError(e); } } Asynchronous Observable }) }) with Multiple Values }
    167. 167. Observableを組み合わせて、サービスを作る こうした情報を返すサービス
    168. 168. Observableを組み合わせて、サービスを作る Observable<Video>は、OnNextにn個のビデオを送り出す
    169. 169. def Observable<Map> getVideos(userId) { return VideoService.getVideos(userId) } Observable<Video>は、OnNextにn個のビデオを送り出す
    170. 170. def Observable<Map> getVideos(userId) { return VideoService.getVideos(userId) // リストの最初の10本だけが欲しい .take(10) } 最初の10個を取って、あとはunscribeする。 10個のビデオを送り出す Observable<Video>を返す。
    171. 171. Observableを組み合わせて、サービスを作る 最初の10個を取って、あとはunscribeする。 10個のビデオを送り出す Observable<Video>を返す。
    172. 172. Observableを組み合わせて、サービスを作る unscribe 最初の10個を取って、あとはunscribeする。 10個のビデオを送り出す Observable<Video>を返す。
    173. 173. def Observable<Map> getVideos(userId) { return VideoService.getVideos(userId) // リストの最初の10本だけが欲しい .take(10) .map( { Video video -> // Videoオブジェクトを変形する }) } map operatorは、入力値を他の出力値に変える
    174. 174. Observable<R> b = Observable<T>.map({ T t -> R r = ... transform t ... return r; })
    175. 175. def Observable<Map> getVideos(userId) { return VideoService.getVideos(userId) // リストの最初の10本だけが欲しい .take(10) .flatMap( { Video video -> // それぞれのビデオからメタデータを取り出す def m = video.getMetaData() .map( { Map<String, String> md -> return [ title: md.get(―title‖), length: md.get(―duration‖)] }) // ブックマークとレイティングも def b .... def r .... }) } ここでは、flatMap / mapMany を使う。 mapでは Observable<T>の 要素一つが、型 Rの要素一つに変わったが、flatMap / mapManyでは、 Observable<T>の要素一つ一つが、別のObservable<R>に変わる。
    176. 176. Observableを組み合わせて、サービスを作る
    177. 177. def Observable<Map> getVideos(userId) { return VideoService.getVideos(userId) // リストの最初の10本だけが欲しい .take(10) .mapMany( { Video video -> // それぞれのビデオからメタデータを取り出す def m = video.getMetaData() .map( { Map<String, String> md -> return [ title: md.get(―title‖), length: md.get(―duration‖)] }) // ブックマークとレイティングも def b .... mapManyは、三つの関数の定義に応じて def r .... Observable<Video>から、次の三つの }) Observableを生成する。 } Observable<VideoMetadata> Observable<VideoBookmark> Observable<VideoRating>
    178. 178. Observableを組み合わせて、サービスを作る 一つのVideo ‗v‘に対して getMetaData()は、 Observable<MetaData>を返す
    179. 179. def Observable<Map> getVideos(userId) { return VideoService.getVideos(userId) // リストの最初の10本だけが欲しい .take(10) .mapMany( { Video video -> // それぞれのビデオからメタデータを取り出す def m = video.getMetaData() .map( { Map<String, String> md -> return [ title: md.get(―title‖), length: md.get(―duration‖)] }) // ブックマークとレイティングも def b .... def r .... }) } それぞれのObservableは、mapを利用して データを変換する
    180. 180. Observableを組み合わせて、サービスを作る Observable<MetaData>は、map関数で変形される
    181. 181. Observableを組み合わせて、サービスを作る Observable<Bookmark>、Observable<rating>も 同様に処理される
    182. 182. def Observable<Map> getVideos(userId) { return VideoService.getVideos(userId) // リストの最初の10本だけが欲しい .take(10) .mapMany( { Video video -> // それぞれのビデオからメタデータを取り出す def m = video.getMetaData() .map( { Map<String, String> md -> return [ title: md.get(―title‖), length: md.get(―duration‖)] }) // ブックマークとレイティングも def b .... def r .... // これらを結合する }) }
    183. 183. def Observable<Map> getVideos(userId) { return VideoService.getVideos(userId) // リストの最初の10本だけが欲しい .take(10) .flatmap( { Video video -> // それぞれのビデオからメタデータを取り出す def m ... def b .... def r .... // これらを結合する }) }
    184. 184. def Observable<Map> getVideos(userId) { return VideoService.getVideos(userId) // リストの最初の10本だけが欲しい .take(10) .flatmap( { Video video -> // それぞれのビデオからメタデータを取り出す def m ... def b .... def r .... // これらを結合する return Observable.zip( m, b, r, { metadata, bookmark, rating -> // 完全なデータの辞書に変換する return [ id: video.videoId ] << metadata << bookmark << rating }) zipは、三つの非同期のObservableを }) 一つのObservableにまとめる }
    185. 185. Observableを組み合わせて、サービスを作る
    186. 186. Observableを組み合わせて、サービスを作る
    187. 187. public Data getData(); を考える -- NetFlix RxJava もしも、同期型から非同期型に変わったら 、実装はどう変化するだろうか? クライアントは、ブロックしないように実 行するには、どうすればいいだろうか?
    188. 188. getDataの実装の候補 public Data getData(); public void getData(Callback<T> c); public Future<T> getData(); public Future<List<Future<T>>> getData();  ...     ?
    189. 189. IterableとObservable Iterable Observable Pull Push T next() onNext[T] throw Exception onError[Exception] returns; onCompletion
    190. 190. IterableとObservable  同じ高階関数が、IterableにもObservableに も、同じように適用出来る。
    191. 191. getData()の分類  同期/非同期、返り値の単数/複数で表を作っ てみると、getData()の次のような分類が可 能である。
    192. 192. String s = getData(args); if (s.equals(x)) { // do something } else { // do something else } scalarを返り値に持つ、典型的な同期型 getData()のコード
    193. 193. Iterable<String> values = getData(args); for (String s : values) { if (s.equals(x)) { // do something } else { // do something else } } scalar値が返る場合とほとんど同じだが、処理はループする
    194. 194. Future<String> s = getData(args); if (s.get().equals(x)) { // do something } else { // do something else } 古いJavaのFutureコード。非同期だが、getでブロックする。
    195. 195. Future<String> s = getData(args); Futures.addCallback(s, new FutureCallback<String> { public void onSuccess(String s) { if (s.get().equals(x)) {...} else {...} } public void onFailure(Throwable t) { // handle error } }, executor); Futureとcallbackをつかった非同期のコード・サンプル
    196. 196. Observable<String> s = getData(args); s.map({ s -> if (s.get().equals(x)) { // do something } else { // do something else }); Observableを使ったgetData()のコード・サンプル
    197. 197. IterableとObservableの「双対 性」  Observable/Observer は、同期型の Iterable/Iterator の非同期の双対形である。  ―Subject/Observer is Dual to Iterator‖ Erik Meijer‖http://csl.stanford.edu/~christos/pldi2010.fit/ meijer.duality.pdf  ―Introduction to the Reactive Framework Part II ‖ http://codebetter.com/matthewpodwysocki/2009/11/03/ introduction-to-the-reactive-framework-part-ii/
    198. 198. Part IV Reactive Manifesto
    199. 199. Reactive Manifesto 2013年9月23日 version 1.1 http://www.reactivemanifesto.org/
    200. 200. Reactiveに移行する必要性  近年、アプリケーションの要請は劇的に変わってきた 。ほんの数年前には、大規模なアプリケーションは、 数十台のサーバ、数秒のレスポンスタイム、数時間の オフライン・メンテナンス、数ギガバイトのデータか ら構成されていた。今日、アプリケーションは、モバ イル・デバイスから数千のマルチコア・プロセッサー が走るクラウド・ベースのクラスターにいたるまであ らゆるところに配備されている。ユーザはミリセカン ドさらにはナノセコンドのレスポンスタイムと、 100%の稼働を期待している。データの要求は、ペタ バイトに拡大しようとしている。
    201. 201.  当初は、GoogleやTwitterといった革新的なインター ネット・ドリブンの企業の領域だけだったが、こうし たアプリケーションの特徴は、ほとんどの産業で表面 化した。金融や通信事業者が、最初に新しい要請を満 たす実践を受け入れ、その他の産業がそれに続いた。  新しい要請は、新しいテクノロジーを要求する。それ 以前のソリューションは、管理されたサーバとコンテ ナに力点を置いたものだった。規模拡大は、より大き なサーバを買うことと、マルチスレッドによる並行処 理を通じて達成された。追加されたサーバは、複雑で 非効率かつ高価なプロプライエトリなソリューション を通じて追加された。
    202. 202.  しかし今では新しいアーキテクチャーが進化し、開発 者が今日の要求を満たすアプリケーションを概念的に 把握し、アプリを構築するのを可能にしている。我々 は、これらをリアクティブ・アプリケーションと呼ん でいる。このアプリケーションは開発者が、イベント ・ドリブンで、拡張性を持ち、耐障害性の高い、応答 性に優れたシステムを構築することを可能とする。す なわち、このアプリケーションは、リアルタイム感に 富み、拡張可能で耐障害性の高いアプリケーション層 で支えられ、マルチコアでもクラウド・コンピュータ のアーキテクチャでもすぐに配備されうる、高い応答 性のユーザ体験を提供出来るアプリケーションである 。 このReactive Manifestoは、リアクティブに移行 するのに必要な本質的な諸特徴を記述するものである 。
    203. 203. Reactive アプリケーション  辞書のMerriam-Websterは、reactiveを「刺激に対 してすぐに反応できること」と定義している。すなわ ち、そのコンポーネントは「アクティブ」で、常にイ ベントを受け取る準備ができているということである 。この定義は、リアクティブなアプリケーションの本 質を捉えている。それはシステムの次のようなところ に焦点を合わせている。
    204. 204.  react to events イベントに反応する イベント・ドリブンの性質は、次のような特 質を可能にする  react to load 負荷に反応する 共有リソースの競合を避けることで、拡張可 能性にフォーカスする  react to failure 失敗に反応する 全てのレベルでエラー回復の能力を持たせる ことで、耐障害性の高いシステムを構築する  react to users ユーザに反応する 負荷のいかんにかかわらず、高い反応時間を 保証する
    205. 205.  これらの一つ一つが、リアクティブなアプリケーショ ンの本質的な特徴である。一方で、それらのあいだに は、相互に従属関係が存在する。ただ、これらの特徴 は、標準的な階層型のアプリケーションの意味での「 層」にあたるものではない。その代わりに、それらは 全ての技術をつらぬいた設計の諸特徴を記述したもの である。
    206. 206. Event-driven 重要なこと  非同期通信に基づいたアプリケーションは、疎結合デ ザインを実装する。それは、純粋に同期型のメソッド 呼び出しに基づいたアプリケーションよりもいいもの である。イベントの送り手と受け手は、如何にイベン トが伝播するのかの詳細を考えなくても実装されるこ とが出来る。インターフェースは通信の内容に集中出 来る。このことで、拡張も改良も保守も、より容易な 実装ができるようになり、開発の柔軟性を増やすと同 時に保守コストを低減出来る。
    207. 207.  非同期通信のメッセージの受け手は、イベントが起き るまで、あるいは、メッセージを受け取るまで、眠っ ていることが出来るので、イベント・ドリブンのアプ ローチは、多数の受け取り手が、単一のハードウェア 上のスレッドを共有することで、既存のリソースを有 効に利用することが出来る。 重い負荷の下にある、ブロックしないアプリケーショ ンは、こうして、ブロックする同期型の通信単位に基 づいた伝統的なアプリケーションより、低遅延と高ス ループットを持つことが出来る。結果として、オペレ ーションのコストは低いものになり、可用性は高まり 、エンドユーザはハッピーになる。
    208. 208. Event-driven キーとなる構成ブロック  イベント・ドリブンのアプリケーションでは、様々な 事実を記述する離散型の情報の断片であるイベントの 生産と消費を通じて、コンポーネントは相互作用を行 う。これらのイベントは、ブロックしない非同期なス タイルで、送られ受け取られる。イベント・ドリブン のシステムは、PullやPollより、Pushに依存すること が多い。すなわち、イベントの消費者にデータをいつ までも要求するか待たせることなく、それが利用可能 になった時点で消費者に向けてデータをPushする。
    209. 209.  非同期のイベントの送信は、メッセージ・パッシング とも呼ばれるのだが、それはアプリケーションが設計 から高度に並列化され、変更なしでマルチコアのハー ドウェアを利用出来るということを意味する。CPU内 の全てのコアがいかなるメッセージ・イベントをも処 理出来るということは、並行実行の可能性を劇的に増 大させる。  ノン・ブロッキングは、エラーや処理の爆発的な増大 が起きた場合でさえも、アプリケーションが、どんな 時でも反応を返すことが出来る為に、処理を連続的に 進める能力を意味する。この為には、反応に必要とさ れる全てのリソースは—例えば、CPU、メモリー、ネ ットワーク等は、独占されてはならない。こうして、 それは低い遅延と高いスループットとより良い拡張性 を可能とする。
    210. 210.  伝統的なサーバサイドのアーキテクチャーは、変更可 能な状態の共有と単一スレッド上のブロック操作に依 存している。両者はともに、こうしたシステムを変化 する要求に適合するようにスケールしようとした時遭 遇する様々の困難の原因となる。変更可能な状態の共 有は、同期を要求する。これは、思わぬ複雑さと非決 定性を導入することになり、プログラムのコードの理 解を難しいものにし、保守も難しいものにする。ブロ ッキングでスレッドを眠らせることは、有限の資源を 浪費し、また、起き上がらせる時に高いコストを払う ことになる。
    211. 211.  イベントの生成と処理を分離することで、ランタイム のプラットフォームは、同期の詳細とスレッドをまた いでいかにイベントが送り出されるかを意識すること が可能となる。一方で、プログラムの抽象はビジネス のワークフローのレベルまで持ち上げられる。スレッ ドやロックといった低レベルの諸機能にかかわること なしに、イベントがどのようにシステムの中を伝播し 、コンポーネントがどのように相互作用するかを考え ればいい。  イベント・ドリブンのシステムは、コンポーネント間 、サブシステム間の疎結合を可能とする。この間接性 のレベルは、あとで見るように、拡張可能性と耐障害 性の前提条件の一つである。コンポーネント間の複雑 で強い従属性を取り除くことで、イベント・ドリブン のアプリケーションは、既存のアプリケーションに最 低限のインパクトを与えるだけで拡張が可能である。
    212. 212.  アプリケーションが、高いパフォーマンスと大規模な 拡張可能性を求める要求の圧力のもとにおかれた時、 どこにボトルネックが生ずるかを予測するのは難しい 。それ故、ソリューション全体が非同期でノン・ブロ ッキングなものであることが重要である。典型的な例 では、このことは、UIのユーザのリクエスト(ブラ ウザーなり、RESTのクライアントなりなんでも)か らリクエストのパージングとweb層での送り出しまで 、ミドルウェアのサービス・コンポーネントに取って は、キャッシングからデータベースにいたるまで、デ ザインがイベント・ドリブンである必要があることを 意味する。  もしこれらの層の一つでもこれに参加せず、データベ ースにブロックするような呼び出しを行ったり、変更 可能な共有状態に依存したり、高価な同期処理を行っ たとすれば全てのパイプラインはとどこおり、ユーザ は遅延の増大と拡張可能性の減尐に苦しめられるだろ
    213. 213.  アプリケーションは、その全体がリアクティブでなけ ればならない。 この鎖の一番弱い環を取り除くことの必要性は、 Amadahlの法則に、よく表現されている。この法則 は、Wikipediaによれば次のように説明されている。  パラレル・コンピューティングで複数のプロセッサー を使ったプログラムのスピードアップは、そのプログ ラムのシーケンシャルな部分によって制限付けられる 。例えば、プログラムの95%が並列化されたとして も、パラレル・コンピューティングを使った理論上の 最大のスピードアップは、次の図に示すように、どん なに多くのプロセッサーを使ったとしても、20倍に とどまる。
    214. 214. Amdahl's Law
    215. 215. Scalable 重要なこと  ―scalable‖という言葉は、Merriam-Websterによれ ば、次のように定義されている。 “要求に応じて、容 易に拡張ないしは格上げが可能であること”. 拡張可能なアプリケーションは、その利用に応じて拡 張することが出来る。これは、アプリケーションに柔 軟性を付加することで達成出来る。要求に応じてスケ ール・アウトまたはスケール・イン(ノードを追加ま たは削除する)することが可能なオプションである。 さらに、アーキテクチャは、アプリケーションの再デ ザインや書き直しなしで、スケール・アップまたはス ケール・ダウン(ノードにより多くのあるいはより尐 ないCPUを配備する)することを容易にする。 柔軟 性は、アプリケーションをクラウド環境で走らせるコ
    216. 216.  拡張可能性はまたリスクを管理するのを助ける。ユー ザの負荷に対してあまりにも尐ないハードウェアしか 提供しないのは、ユーザの不満足を引き起こし、顧客 を失うことになる。逆に、理由もなく遊んでいる多く のハードウェアとオペレーションの要員を与えるのは 、不必要な経費でしかない。拡張可能なソリューショ ンは、使うにふさわしい新しいハードウェアを使うこ とが出来ずに、アプリケーションを使い続けるリスク を緩和する。10年以内には、我々は、ことに数千で はないにしろ数百のハードウェア・スレッドが走るプ ロセッサーを見ることになるだろう。こうした潜在的 な可能性は、アプリケーションが、非常に細かな粒度 のレベルでスケーラブルであることを要求している。
    217. 217. Scalable キーとなる構成ブロック  非同期のメッセージ・パッシングに基づいたイベント ・ドリブンのシステムは、拡張可能性の基礎を提供す る。コンポーネントとサブシステム間の疎結合と位置 独立性は、同じセマンティックをもった同じプログラ ミング・モデルを維持したまま、システムを複数のノ ードにスケールアウトすることを可能にする。 コン ポーネントのインスタンスを追加することで、システ ムのイベント処理の能力は増大する。実装に関して言 えば、複数のコアを利用してスケール・アップするこ とと、データセンターやクラスターで沢山のノードを 利用してスケール・アウトすることの間に違いはない 。
    218. 218.  アプリケーションのトポロジーは、アプリケーション の利用に応じた配置やランタイムのアルゴリズムの採 用を通じて表現される配備の決定になる。このことを 、位置透過性と呼ぶ。  目標は、透過的な分散コンピューティング、分散オブ ジェクト、RPCスタイルの通信を実装しようと試みる ことなどではないのだと理解することは重要である。 こうしたことは以前に試みられ、そして失敗してきた 。我々に必要なことは、非同期メッセージ・パッシン グを通じたプログラミング・モデルで直接に表現され るネットワークを擁護することなのである。真の拡張 可能性は、分散コンピューティングを自然に含み、そ してそこには、本質的に信頼出来ないと言っていい、 ネットワークをまたぐことを意味するノード間の通信 が含まれている。
    219. 219.  それゆえ、プログラミング・モデルの中で、物事を「 簡単にする」という見落としの多い抽象の背後にそれ らを隠すことなく、ネットワーク・プログラミングの 制約やトレードオフや失敗のシナリオを明確にするこ とは重要である。 結果として、分散環境で起きてくる典型的な問題を解 決する為の共通の構成ブロックをカプセル化するツー ル – 高い段階の信頼性を提供する合意の形成やメッ セージの抽象を与えるようなツールを提供することは 、同じように重要なことである。
    220. 220. Resilient 重要なこと  アプリケーションのダウンは、ビジネスに起きうるも っともダメージの多い問題の一つである。通常の帰結 は、オペレーションが単に止まっただけでも、収入の 流れに穴があいたままになるということである。長い 期間でみれば、それは顧客の不満と悪い評判につなが って、ビジネスをもっと深刻に傷つけることになりか ねない。アプリケーションの対障害性が、大部分では 無視されたり、経験的なテクニックで対応されている 要請であることは驚くべきことである。このことは、 あまりに荒い粒度のツールを使うという粒度のレベル の間違いに基づいていることを意味する。
    221. 221.  実行時やサーバのエラーからの回復の為に、通常は、 アプリケーション・サーバのクラスタリングの手法を 用いる。不幸なことに、サーバのフェール・オーバー は、非常にコストがかかる、しかも危険なものである 。それは、潜在的には、失敗の連鎖をおこして全ての クラスターの停止を招きかねない。コンポーネント・ レベルの細粒度の耐障害性を利用して対応すべきこと を、事故管理の間違ったレベルの粒度で対応している というのは、こうした理由に基づく。  Merriam-Websterは、耐障害性を次のように定義し ている。  実体あるいはオブジェクトの、もとの形に戻ろう とする能力。  困難からすぐに立ち戻る能力
    222. 222.  リアクティブ・アプリケーションでは、耐障害性は結 果論ではなく、最初からデザインの一部である。失敗 を、プログラミング・モデルの中で、第一級のクラス の構成物とすることは、それに反応しそれを管理する 手段を提供することを意味する。それは、アプリケー ションを、それらを実行時に修復し回復する能力を持 たせることで、失敗に対して高い耐久性を持たせるこ とになる。伝統的な障害の処理は、こうしたことを達 成出来ない。なぜなら、それは、例外が発生した時に はいつでもどこでもそれを処理するか、あるいは、障 害が起きたらアプリケーションの全てのインスタンス をフェールオーバーするかということで、小規模なも のではあまりに防御的で、大規模なものにはあまりに 攻撃的だからである。
    223. 223. Resilient キーとなる構成ブロック  失敗を管理する為には、それが他の健全なコンポーネ ントに広がらないようにそれを隔離する手段と、また 、失敗のコンテキストの外側の安全な地点からそれを 観察する手段を必要とする。思い浮かぶ一つのパタン は、次の絵に示すような「隔壁」というパターンであ る。そこでは、システムはそれらに一つで事故が発生 しても他の部分は影響を受けないように、安全な区域 によって構成されている。これは、古典的な問題であ る事故の連鎖を防止し、管理の問題を隔離することを 可能にする。
    224. 224.  拡張可能性を可能とするイベント・ドリブン・モデル は、事故管理のこのモデルを実現する為の必要な基本 的な単位でもある。イベント・ドリブン・モデルの疎 結合は、事故はそのコンテキストとともに補足される とともに、メッセージとしてカプセル化され、他のコ ンポーネントに送られてエラー検知を可能にしそれに どう対応するか決定出来るように、完全に隔離された コンポーネントを提供する。
    225. 225.  このアプローチは、ビジネス・ロジックはクリーンに 残し、予期しなかったことの処理から分離したままで 、事故は区分けされ観察され管理され、そして宣言的 な仕方で処理されるようなシステム、そこでは、シス テムは自分自身を自動的に修復し回復出来るようなシ ステムを作り出す。それは、大きな企業では、問題は それを処理する権限を持ったレベルの部署に到達する まで上層部に伝えられるのとほとんど同じように、区 分けが階層的な仕方で構造化されていると最もうまく 機能する。  このモデルの美しい点は、それが純粋にイベント・ド リブンで、リアクティブなコンポーネントと非同期の イベントに基づいており、それ故、位置通過的である ことである。 実践的には、このことは、分散環境においても、ロー カルなコンテキストでの同じセマンティックでそれが 動くことを意味する。
    226. 226. Responsive 重要なこと  Responsiveは、 Merriam-Webster によれば「応 答が素早く、適切に反応すること」と定義されている 。我々は、この言葉をそうした一般的な意味で用いる 。それは、Webデザインにおける Responsive Web Design と混同されてはならない。それは、もともと は、CSSのmedia queryとその改良・強化にかかわ るものだ。  Responsiveアプリケーションは、リアルタイムで魅 力的で豊かで共同的なものだ。ビジネスはその顧客と 、レスポンシブでインタラクティブな経験を通じて顧 客を歓迎することで、オープンで進行する対話を作り 出すことが出来る。
    227. 227.  それはビジネスをより効率的なものにし、人々はつな がっていて問題を解決し課題を達成する手段を持って いるという感覚を作り出す。一つの例が、Google Docである。 それはユーザがドキュメントを共同で 編集することを可能とし、リアルタイムに、参加者が 互いに編集やコメントを、書いたらすぐに生き生きと 見ることが出来る。  イベントに反応するアプリケーションは、たとえ事故 があったとしてもタイムリーな仕方でそれを行う必要 がある。もし、アプリケーションが、別の言い方をす ると遅延と見なされる、適切な時間の制約以内で反応 しなかったら、それは実際には使い物にはならなくて 、それ故、耐障害性を持つとは考えられなくなる。
    228. 228.  厳しい実時間システムの制約に応えることが出来ない ことは、軍事や医療コントロールシステムのようなア プリケーションの場合には、システム全体の事故と見 なされる。全てのアプリケーションが、こうした厳し い要請を持つ訳ではない。多くのアプリケーションは 、応答時間の制約から外れると、急速に有用性が失わ れるのを見ることになる。例えば、金融トレーディン グのアプリケーションは、タイムリーな応答なしには 、現在の取引を失うことになる。  小売りやネット購買のような、主流のより多くのアプ リケーションは、反応時間が遅くなるにつれ確実に有 用性が落ち始める。ユーザが、レスポンシブなアプリ ケーションと相互作用すればするほど、購買のボリュ ームは増大する。
    229. 229. Responsive キーとなる構成ブロック  リアクティブなアプリケーションは、Observableな モデルとイベント・ストリーム、クライアントの状態 を利用する。  Observableモデルは、状態が変わった時に、他のシ ステムがイベントを受け取ることを可能とする。この ことは、ユーザとシステムとのあいだにリアルタイム の接続を提供する。例えば、複数のユーザが同じモデ ルで同時に仕事をしていた時、変化は彼らの間でリア クティブに双方向に同期されうる。こうして、そのモ デルはロックの制約なしに共有されているように見え る。
    230. 230.  イベント・ストリームは、その上にこうした接続が構 築される基本的な抽象を形成する。これらをリアクテ ィブにすることは、ブロッキングを排除して、その代 わりに、非同期でノンブロッキングな転送と通信を可 能とする。  リアクティブ・アプリケーションは、デザイン・パタ ーンとテストを利用してアルゴリズムの順序を守る。 これによって負荷のいかんにかかわらずイベントへの 応答がO(1)あるいは尐なくともO(log n)時間で返る ことを保証する。このスケール因子には、顧客、セッ ション、製品、取引を含むことが出来るが、それに限 られない。
    231. 231.  それらは、負荷のプロファイルのいかんにかかわらず 応答の遅延を一定にするように、いくつかの戦略を利 用している。  爆発的なトラフィックの条件下では、リアクティブ・ アプリケーションは、遅延を一定のものに保つ為に、 リソースをある了解と配慮の下で、結合したバッチ処 理を適用して、IOや同時並行でのデータの交換のよ うな高価な処理を、後回しにする。  キューは適切なバックの圧力で制限されている。キュ ーの長さは、与えられたレスポンスの制約条件の下で 、Littleの法則を適用することで決定される。  システムは、その場で計画された適切な容量でモニタ ーされる。  事故は、回路遮断機がトリガーされると、あらかじめ 利用可能にされている代替処理戦略によって隔離され る。
    232. 232.  レスポンシブ・アプリケーションの例として、ブラウ ザ・ベースであれモバイル・アプリであれ、魅力的な ユーザ経験を作り出す、リッチ・クライアントの Webアプリを考えよう。このアプリケーションは、 クライアント側でロジックを実行し状態を記憶してい るしよう。Observableモデルは、データが変更され た時、リアルタイムでユーザ・インターフェースを変 更するメカニズムを提供する。WebSocketや Server-Sent-Eventのような技術が、ユーザ・イン ターフェースを直接にプッシュされたイベント・スト リームに接続することを可能とする。こうして、イベ ント・ドリブン・システムは、バックエンドからクラ イアントにいたるまで、あらゆる方法で拡張される。 このことが、リアクティブ・アプリケーションが、非 同期でノン・ブロッキングなデータ転送を使って、ブ ラウザやモバイル・アプリに、スケーラブルで耐障害 性を持ったやり方で、イベントをプッシュすることを
    233. 233.  このことを心に留めておけば、いかにして四つの特質 、イベント・ドリブン、拡張可能性、耐障害性、レス ポンシブが、相互に関連し全体として密接に結びつい ていることは、明らかになる。
    234. 234. 結論  リアクティブ・アプリケーションは、ソフトウェア開 発の現代における幅広い挑戦に向けられたバランスの 取れたアプローチを表現している。イベント・ドリブ ン、メッセージ・ベースの基礎の上に硬直されること で、それは拡張可能性と耐障害性を保証するのに必要 なツールを提供している。これらの上に、それは豊か でレスポンシブなユーザ・インタラクションをサポー トしている。我々は、この数年以内にこの青写真に従 うシステムの数が、急速に増えていくことを期待して いる。
    235. 235. 参考資料  Meteor  AngularJS  polymer.js
    236. 236. Meteor Concept  Structuring your app  Data and security  Reactivity  Live HTML  Templates
    237. 237. Meteorアプリケーションの構造  Meteorアプリケーションは、クライアントのWebブ ラウザの内部で走るJavaScriptと、Node.jsコンテ ナーの内部のMeteorサーバー上で走るJavaScript、 それにサポートされている全てのHTMLフラグメント とCSSルール、静的なアセットから構成される。  Meteorは、これらの異なるコンポーネントのパッケ ージングと連携を自動化する。ファイル・ツリーの中 で、これらのコンポーネントに、どのような構造を選 ぶかについては、Meteorは、極めて柔軟である。
    238. 238. Data and security
    239. 239. In Memory DB Cache  全てのMeteorクライアントは、イン・メモリーのデ ータベース・キャッシュを持っている。  このクライアントのキャッシュを管理する為に、サー バーは、JSONドキュメントの集合をpublishし、ク ライアントは、これらの集合にsubscribeする。  集合内のドキュメントが変化すると、サーバーは、そ れぞれのクライアントのキャッシュを変更する。
    240. 240. publish function  それぞれのドキュメントの集合は、サーバー上の publish関数によって定義される。  publish関数は、新しいクライアントが、ドキュメン トの集合に対してsubscribeするたびに、実行される 。  ドキュメントの集合の中のデータは、どこから来ても いいのだが、一般的な場合は、データベースのクエリ ーをpublishすることである。
    241. 241. // server: publish all room documents Meteor.publish("all-rooms", function () { return Rooms.find(); // everything ); // server: publish all messages for a given room Meteor.publish("messages", function (roomId) { return Messages.find({room: roomId}); }); // server: publish the set of parties the logged-in user can see. Meteor.publish("parties", function () { return Parties.find({$or: [{"public": true}, {invited: this.userId}, {owner: this.userId}]}); });
    242. 242. subscribe  いったんsubscribeされると、クライアントは、その キャッシュを高速なローカル・データベースとして利 用するので、劇的に、クライアントのコードは、単純 化される。  Readは、サーバーへの高価な回り道を、要求される ことはない。 そして、それらは、そのキャッシュの 内容に限られている。クライアント上の集合中のドキ ュメント全てに対するクエリーは、サーバーがクライ アントにpublishしたドキュメントを返すのみである 。
    243. 243. // client: start a parties subscription Meteor.subscribe("parties"); // client: return array of Parties this client can read return Parties.find().fetch(); // synchronous!
    244. 244. allow/deny rule  クライアントが、いくつかのドキュメントを変更した 時、クライアントはサーバーに、その変更を要求する メッセージを送る。  サーバーは、提案された変更を、JavaScriptの関数 で書かれたallow/denyルールに照らしてチェックす る。  サーバーは、全てのルールをパスした変更のみを受け 入れる。
    245. 245. // server: don't allow client to insert a party Parties.allow({ insert: function (userId, party) { return false; } }); // client: this will fail var party = { ... }; Parties.insert(party);
    246. 246. データの更新と伝搬  サーバーが変更を受け付けると、サーバーは、データ ベースにその変更を適用して、影響を受けたドキュメ ントにsubscribeしていた他のクライアントに、その 変更を、自動的に伝搬する。  もし、受け付けなかったら、更新は失敗する。サーバ ーのデータベースは、変わらないまま残り、他のクラ イアントは、誰も、更新を見ることはない。
    247. 247. データの更新と伝搬  Meteorは、キュートなトリックも使う。クライアン トがサーバーに対して書き込みをしようとした時、サ ーバーの返答を待つこと無しに、ローカルキャッシュ をただちに書き換える。このことは、スクリーンは、 ただちに再描画されることを意味する。  もし、サーバーが更新を受け付けた時、これは 、ク ライアントが正しく動作している時には、大部分の時 間は、そうなるべきなのであるが、クライアントは、 変化にただちにジャンプして、スクリーンを更新する のに、サーバーへの回り道を待つ必要がない。
    248. 248. Reactivity
    249. 249. Reactive Programming  Meteorは、reactive programmingのコンセプトを 擁護する。このことは、コードを単純な命令スタイル で書くことを可能にし、その結果は、コードに従って 、データが変更された時にはいつでも、自動的に再計 算されることを意味する。

    ×