ぼちぼち日記

おそらくプロトコルネタを書いていることが多いんじゃないかと思います。

Node.js-v0.10リリースアナウンスの簡単な解説と感想など

1. はじめに、

昨年6月末に node-v0.8がリリースされて8か月半ほど経って node-v0.10 がリリースされました。私もいくつかパッチがこのリリースに採用されていまして、ちょっと感慨深いです。
当初1月末のリリース予定でしたが、やっぱり今日まで延びました。安定版リリース直前のゴタゴタはもうNodeの風物詩なんですね。

今回、Node-v0.10のリリースにあたり、 isaacs から次のリリース文
http://blog.nodejs.org/2013/03/11/node-v0-10-0-stable/
がポストされています。英語かつ長文なので内容をちゃんと読み切れな方もいらっしゃるかと思いますので、リリース文の項目にあわせて私の視点で簡単な解説と感想などを書いてみます。(ちゃんとリリース文を理解された方はわざわざお読みにならなくても大丈夫です。)

尚、このリリースはこれ以外にも変更がいっぱいあります。libuv なんぞ大改造しているんですが、これはまたの機会にしたいと思います。

2. バージョンは 0.10なの? 1.0 じゃないの?

予定では次は node-v0.12 になり、1.0 へのリリース準備が整います(後述)。 1.0というのは主にマーケティングなバージョン付けなので別に技術的にどうこうなったものではないという位置づけです。(以下参照)
Node.js-v1.0 リリースに向けてどうなる?
今回の Stream APIの変更もそうですが、今後API後方互換性を最大限に確保し、安定性や性能向上を中心に開発が進められます。

だから、もう node-0.X だからといってあまり不安視される必要はない、と個人的には思います。(ただし実験的や今後導入されるかもしれない新機能などは除きます)

3. Streams2

今回のリリースの目玉となっています。この変更を行った理由は、東京Node学園祭で isaacs の講演で説明されてた通り、

  • リスナ登録タイミングによる data イベントからのデータの取り損ない
  • 不安定なストリーム処理時 pause, drain, resume の頻発による性能劣化

を解決することにあります。

一例として、以前との表面上の違いは dataイベント、 pause(), resume() がなくなり、readable イベントと read() を使うといったところです。ただ後方互換性を保っているので従来のコードはそのまま動作します。(1つ例外があります。)

簡単な例として、クライアントからPOSTデータを受信して表示するHTTPサーバのコードを比べてみましょう。 Stream1 では、

// HTTP Server for receiving POST data with Stream1
var http = require('http');
var server = http.createServer(function(req, res) {
  var data = '';
  req.on('data', function(chunk) {
    data += chunk;
  });
  req.on('end', function() {
    console.log('POST data:' +  data);
    res.writeHead(200);
    res.end();
  });
});
server.listen(1337);

になりますが、Stream2 では以下のようになります。

// HTTP Server for receiving POST data with Stream2
var http = require('http');
var server = http.createServer(function(req, res) {
  var data = '';
  req.on('readable', function() {
    data += req.read();
  });
  req.on('end', function() {
    console.log('POST data: ' + data);
    res.writeHead(200);
    res.end();
  });
});
server.listen(1337);

他にもいろいろありますが、残念ですがこれ以上はとても長くなるので今回は止めておきます。また何かの機会にでも。

4. Domains and Error Handling

以前の Domain ではエラー処理に process の uncaughtException イベントに依存していたため、
「ネストされたドメインの奇妙な振る舞い」 のようなことが発生していました。

今回この依存性をなくし、この問題が解決しています。先のブログ記事の例も試してみると node-v0.10では正常に動作するようになっています。そして Domain APIが Experimental から Unstable に昇格してます。

uncaughtException イベントを廃止するかどうか議論になりましたが、長らく使われているため継続されることになりました。でも今後なるべく使わないようにするものとして扱われるでしょう。

5. Faster process.nextTick

以下のスライドの p22〜24に書いてある process.nextTick の動作仕様の変更が行われました。

node-v0.10 では process.nextTick() を使った再帰計算は、process.maxTickDepth(デフォルト1000) まで連続に再帰を行ってからイベントループを回しますが、node-v0.11以降できなくなります。 これから再帰計算を行うなら setImmediate() を使うことが推奨されます。

6. Latency and Idle Garbage Collection

node-v0.8以前は、128MB以上のヒープを使ったり、前回のGCトリガーから5秒以上経過していると、Idle時(IOイベント処理がないとき)にV8へ IdleNotification をキックしてGCを行う処理が入っていましたが、今回これが撤廃されました。

ベンチマークでもそれほど悪化していないので、Node側からのGC制御をなくし全部V8に任せてもうまくやってくれるとの判断です。この辺誰か詳しい人が解説してくれないですかねぇ。

7. Performance and Benchmarks

isaacs による node-v0.8 と 0.10 の性能比較結果。 あまり細かく見ていませんが、libuvや stream の大改造をしたにも関わらずいい数字をだしていると思います。

毎回いろいろ細かい性能向上向けの修正を行っていますが、今回日本のコントリビューター @tricknotes さんによる EventEmitter のパッチ https://github.com/joyent/node/pull/4393 などは、ボディブローのように Node 高速化に寄与しているんじゃないかなと個人的に思っています。

リリース直前にisaacs がベンチマークスクリプトの整備を行っていたので、時間が取れれば自分でも試してみたいと思います。

8. Continuous Integration

TJ がNodeのテストを tap 出力するパッチを書いてくれたので、Jenkinsと組み合わせて CI することを始めましたようです。
http://jenkins.nodejs.org/
今後は Nightly ビルドを提供することを計画しているとのこと。

今までNodeのリリース作業は結構属人的になってましたが、将来の安定版のリリースは、いつでも必要なときにこの Nightly を持って行ってくれ、となるかもしれません。

9. Growing Out

今後、Nodeイノベーションの中心はコアではなくユーザランドのモジュールを中心にしていくということ。

今コアのモジュールで実現できている機能も新しく作り直す時は、ユーザランドのモジュールで開発を行っていくようです。おそらく node-v0.12 で行う新しいHTTPモジュールもユーザランドで開発・試験を行っていくでしょう。

10. Growing Up

Nodeを使った実サービスが既に多く始まっており、エンタープライズに向けに環境も整備されつつという話。

いくつか紹介されていますが、注目すべきは StrongLoop という新会社。
http://strongloop.com/
Nodeコアの中心開発者 Ben Noordhuis と Bert Belder が創業したベンチャーでNodeの商用サポートやディストリビューションの提供などを開始したとのことです。RedHatみたいに商業的に成功して欲しいですね。

11. Next Up: v0.12

次のバージョン Node-v0.12 では HTTPモジュールの大改造を予定しているとのこと。 クライアントとサーバのコードを分離して、Agentで実現しているコネクションプーリングをもっと柔軟に扱えるようにする予定だそうです。

他にもtlsnappy で試験しているTLS性能向上の取り組みも取り入れられる予定。

12. Node-1.0

node-v0.12がリリースされたら 1.0 のリリースです、先に書いたように 1.0 というのはマーケティング issue なので、0.12 からそれほど大きな変更はない予定です。バグ修正や新機能の追加は継続して行うけど、V8のリリースに合わせたりなんらかの自動リリース(ブラウザみたいな定期リリースかな?)の仕組みを考えるかもとのことです。

Nodeコアの開発としてはほぼ終了したとの位置づけです。

最後に

なにはともあれ、無事リリースができてよかったです。ほぼ年中無休で開発・issue対応しているフルタイムのNodeコアチームの苦労はすごいものがあります。彼らの多大な貢献に感謝の意を表したいと思います。