東京NODE学園 3時限目

DOMAINS   &   ISOLATES
      @koichik
自己紹介

 @koichik, id:koichik
 JavaScriptとの関わり
   1997年頃に仕事でServer-Side JavaScript
     Netscape LiveWire, Microsoft IIS
 Nodeとの関わり
   2010/08から触り始める
     APIドキュメント翻訳
     node-handlersocket
   2011/07から (なぜか) コアチーム入り
     ろくに貢献できてないので頑張りますー
Node安定版の歴史

 v0.2 (2010/08/20)
 v0.4 (2011/02/10)
   SSL/TLSのオーバーホール
   新しいHTTPクライアントAPI
   組み込みデバッガ
 v0.6 (2011/11/04)
   ネイティブWindowsサポート
   クラスタリング
   さらに新しいHTTPクライアントAPI
次期安定版

 v0.8
   2012/01リリース予定
   V8のリリースサイクルに合わせて
    短期間で頻繁なリリースを目指す
 新機能の目玉
   Domains
   Isolates
担当するのはこの人達
Domains担当                              Isolates担当
@piscisaureus             @ry          @bnoordhuis




                @isaacs         @cramforce
注意

 現在絶賛開発中
 仕様も実装も激変する可能性大
 話半分ということで
Domains
エラーハンドリング

 EventEmitterで'error'イベントが発生
  リスナがなければ例外がスローされる
 例外がイベントループに達する
  processで'uncaughtException'イベントが発生
 processで'uncaughtException'イベントが
 発生
  リスナがなければスタックトレースを
   出力してプロセスは終了
   http://d.hatena.ne.jp/koichik/20111213
エラー処理の粒度

 EventEmitter
   細かすぎる
 process
   大雑把すぎる
そこで

 関連するイベントをひとまとめに
  それがDomains
  適切な粒度でエラーハンドリング可能
 Domainsにまとめられるイベント
  対応モジュール (11/12/13時点)
    net (tls, http, https)
    dns
    fs
    timers
  handleとして抽象化
Domainsの使い方

 実装はdomains2ブランチ
  masterにはマージされていない
 デフォルトはDomains無効
  --domainsオプションで有効化
 domainsモジュール

  var domains = require('domains');
ドメインの作成

 domains.createDomain(arg, cb)
   新しいドメインを作成して返す
   イベントループに戻った後、
   作成されたドメインでcbが呼び出される
     コンテキストベース
     createDomain()の第1引数argがcbに渡される
   cb内で行うI/O等は作成されたドメインに
   関連づけられる
「現在の」ドメイン
                    (デフォルトドメイン)
                                          デフォルトドメインに
                                              関連
var req = http.request(...);
var myDomain = domains.createDomain(null, function() {

                         (myDomain)
                                              これらは
   var req = http.request(...);              myDomainに
                                                関連
   setTimeout(function() {...}, 10000);

                                          デフォルトドメインに
});                                           関連
setTimeout(function() {...}, 10000);
ドメインのエラー処理

 'error'イベントのリスナを登録する
  myDomain.on('error', listener)
 ドメインに関連づけられたI/O等で
  発生したエラーをまとめて処理
 ドメイン内の他のI/Oはキャンセルされる
HTTPサーバでの利用例
http.createServer(function(req, res) {
  var myDomain =
      domains.createDomain(null, function(arg) {
    ... // リクエストを処理
  });
  myDomain.on('error', function(err) {
    res.writeHead(500);
    res.end();
  });
});
エラーハンドリング (v0.8~)

 EventEmitterで'error'イベントが発生
  リスナがなければ例外がスローされる
 例外がイベントループに達する
  非デフォルトドメイン実行中ならそのドメインで
   'error'イベントが発生
  デフォルトドメイン実行中ならprocessで
   'uncaughtException'イベントが発生
 processで'uncaughtException'イベントが発生
  リスナがなければスタックトレースを出力して
   プロセスは終了
domainsのその他API

 domains.getCurrent()
   現在のドメインを返す
 domains.add(handle)
   handleを現在のドメインに追加
 domains.remove(handle)
   handleを現在のドメインから削除
 domains.addDefaultDomain(handle)
   handleをデフォルトドメインに追加
DomainオブジェクトのAPI

 domain.kill()
   ドメインに関連づけられたI/O等(handle)を
    全てキャンセル
Domainsのまとめ

 関連するI/O等をまとめることができる
  エラー処理をまとめることができる
  まとめてキャンセルすることができる
 課題
  どのようにドメインを構成するか?
Isolates
かなり昔のV8
                          V8

 static変数を多用            Context
  マルチスレッド非対応
                         Context
 複数の「Context」を利用可能
  独立した空間
  Chromeでは<iframe>ごとに
   Contextを作成
  Nodeではvmモジュールで
   利用可能
今時のV8

 Isolate
   独立したVMのインスタンス
   1プロセスで複数のIsolateを利用可能
   マルチスレッド対応
   Isolateは複数のContextを利用可能
                  V8
    Isolate     Isolate       Isolate
    Context    Context        Context


    Context    Context        Context
V8のIsolateを使うと



      Nodeでも
    マルチスレッドが
    利用可能に!!
Isolates

 V8のIsolateを利用
 マルチスレッド対応
  スレッド毎に一つのV8 Isolate
  スレッド毎に独立したイベントループを持つ
  Isolate間の共有変数はない
IsolatesのAPI (1)

 低水準API (非public)
  process._newIsolate()
  process._joinIsolate()
  いずれ@jovi0608が解説してくれるはず!
IsolatesのAPI (2)

 高水準API
  child_process改めexec.fork()
    Isolatesが有効だと子プロセスではなく
     別スレッドでV8 Isolateを起動
    同じアプリをマルチプロセスでも
     マルチスレッドでも実行可能に
    もちろんcluster.fork()も同様
cluster

      デフォルト                   Isolates有効
     (Isolates無効)
                                  Process

          Process                  Isolate
         (Master)                 (Master)




   Process       Process    Isolate       Isolate
  (Worker)      (Worker)   (Worker)      (Worker)
なぜ(今さら)マルチスレッド?

 本当のところは知りません
 以下推測 (妄想) でお送りします
クラウド企業に支えられるNode

   コアメンバーの6/8が関連企業に所属


  Joyent       @ry         @isaacs   @piscisaureus   Cloud9 IDE




Rackspace   @bnoordhuis   @pquerna    @igorzi         Microsoft
PaaSでの利用形態(1)

 シングルコアのVMで一プロセス




Process   Process   Process   Process




 VM        VM        VM        VM
PaaSでの利用形態(2)

 複数コアのVMで複数プロセス




Process   Process        Process   Process




                    VM
PaaSでの利用形態(3)

 複数コアのVMで複数スレッド


                  Process


Thread   Thread             Thread   Thread




                    VM
Isolatesの狙い (推測)

 性能 (CPU以外のボトルネックがなければ)
  複数VM ≒ 複数プロセス ≒ 複数スレッド
 必要なリソース
  複数VM > 複数プロセス > 複数スレッド
 Isolatesにより
  PaaS提供側のメリット
    少ないリソースで同等の性能を提供可能
  PaaS利用側のメリット
    同等の性能を低コストで利用可能
忍者に聞いてみよう!
Isolatesまとめ

 V8 Isolateを利用してマルチスレッドを
  利用可能に
 マルチスレッドによるクラスタも可能に
 同じアプリケーションがマルチプロセスと
  マルチスレッドどちらでも動作可能
 課題
  アドオン
   マルチスレッドに対応していないと使えない
   またふるい落とされるアドオン増加?
Q&A
ご清聴ありがとうございました

 JavaScript Advent Calendar 2011
  (Node.js/WebSocketsコース)
   http://atnd.org/events/21979
   参加してね!!

東京Node学園#3 Domains & Isolates