nodeconf.eu 2日目 (node.js in production, jschan, debugging)

さてさて二日目。

ひょんなことから円卓で座って会話したらイギリス英語とアメリカ英語の話になって、

「なんでナスってアメリカだとeggplantなんだよ、卵って紫じゃないだろw」
「イギリスのaubergine ってなんだよ、覚えられないよw」

みたいな会話に巻き込まれて、

「いやいや、そんな野菜よりも色のgreyとgrayの差のほうが深刻で、間違えやすいよ、CSSとかでどうしてるの?」

って言ったら

「ウェブの標準はアメリカ英語だから」

っていうマジレスを受けました。

二日目のセッションも色々と聞いてきてすげー面白かったので、まとめていきます。

node.js in production

ab testing in netflix

netflixでやってるAB testingの話。テンプレートをどうやって管理してるのかっていう話とかがあって面白かった。

Building high quality services at Uber

Uberがやってる高品質なサービスを本番で運用するための方法


Fullstack microservices framework by mcollina

GraftJSって呼ばれるmicroservicesを作るためのフレームワークを作っているという話。
中でjschanっていうlibchanのjs実装を作っていてすごく面白かった。


dtrace workshop by max burning

これが結構ネットワークが不安定でWorkShopとして機能してなくて厳しかった。
ただ、かなりdtrace, mdb, lldbが強力だということがわかったので積極的に使っていきたいと思う。


懇親会にて

Fedor Indutny (node.js core team) へのインタビュー

Q. やっとIndutny見つけた!v0.12をリリースしてない一番の障害って何?
A. async listenerの決着がついてないことだね。その辺りもうすこし改善しないといけないと思ってる。

Q. ちなみにTJは性能が安定してないって言ってたけど
A. それもあるよね。性能改善はこっちも重要な要素だと思ってる。

Q. じゃあ性能が改善されてasync listenerに決着がついたらv0.12出せそう?
A. 僕はそう思ってるよ。詳しくはTJに聞いて欲しいけど、僕はそう思う。

Q. ちなみに私的な質問なんだけど、年齢はいくつ?
A. 24歳だよ。

(一緒に写真撮り忘れた)


matteo collina (mosca, jschan, graft committer)へのインタビュー

Q. jschanの話おもしろかった。jschanってwsとspdy両方サポートしてるけどなんでなの?
A. websocketはブラウザで使う目的だね、spdyはブラウザというよりもサーバー間の連携で使うようにするために作ったんだよ。基本的に双方向性はjschanでは不要だったから(request-response形式である必要がないから)spdyのサーバーpushで一方的に送れる方が良かったんだよね。

Q. graftってmicroservicesフレームワークってことだけど、どういう所で使われることを想定してるの?
A. webアプリとかでも良いだろうし、可能性はたくさんあると思ってる。ゲームとかでも使えるんじゃないかな。

Q. microservicesってSingle Point Of Failure を作らないことが重要だって言ってたけど、エンドポイントのところをどうやってケアしようとしてるの?
A. 協調アルゴリズムにRaftを使ってRaftで自分の情報を多重化して持つような仕組みを考えてる。もう少ししたらnode.jsでRaftみたいなgossip protocolをしゃべるモジュール作ろうかなと思ってる。それよりもまずはgraftのService Discovery protocolのほうが先かなー。

Q. mosca日本で流行りはじめてるよ。ただ僕も含めてまだ知らないユーザーが多いから、日本に来れたらmosca meetup 開くよ!
A. おお!やったー!!!それはいいね。日本に行きたいけど、11月は無理そうだから調整しよう!

Raynos (mercury, uber)へのインタビュー

Q. 発表めっちゃ良かった。ちなみにpotterってオープンソースなの?
A. まだオープンソースにしてない。近いうちにオープンソースにするよ。

Q. 日本の開発者がvirtual DOMに目覚めはじめてる、mercuryって今後のRoadmapどうしていくの?
A. プロファイルできるようにしたいと思ってる、もう少しメモリ管理周りをちゃんとしたいと思ってる。

Q. 初歩的な質問なんだけど、 mercuryってサーバーでもクライアントでも使えるの?
A. もちろんだよ。そう設計してあるよ。


Domenic (traceur-compiler)へのインタビュー

Q. めっちゃしゃべってみたかったdomenicだ!!握手しよう!
A. sure!!

Q. traceur-compiler使ってるよ、あれ使うとES6でかけるしイケてるよね。ところで他にもes6-shimsってたくさんあるけど、domenic的にはどれが一番いいと思うの?
A. もちろんtraceur-compilerだね。一番機能が多いし。

Q. 機能多いけど、生成されるjavascriptが読みにくいよね。
A. そうだねー、生成されるJavaScriptは読みにくいよね。まぁ一応ソースマップはあるからデバッグはそこまで難しくないだろうけど、スタックトレースとかは厳しいよね。

Q. es-nextとかes6nowとかだと読みやすいコードで出してくれるからああいうの使いたいと思う事多いんだけど。
A. そうだけど、彼らのES6機能はフルセットではサポートしてないよね。まぁ問題としては認識してるよ。

Q. traceur-compilerの性能はどうなの?
A. あんまり問題ないよ。普通に使う分には問題にはならないかなぁ。

Q. letとか使うと性能落ちるよね。
A. そうだね、中でtry-catch してるから。僕が送ったp-rではもう少し改善されてるはず。そのうち改善されるんじゃないかな。

Q. traceur-compilerにTypesとかAnnotationってあるよね。あれってES6に入らないの?
A. ちょっとむずかしそうだね、ES6はもうバージョンがこれ以上上がらないことが言われてるから。ES7とかは分からないけど、今のところほしいっていう人そんなにいないんだよね。もしもangularがTypesとAnnotationが標準で欲しくなったら誰か提案するんじゃないかな。僕もそこまで必要だと思ってない。

Q. 日本ではTypeScriptをやってる人が割と多くて彼らはJavaScriptに型が欲しいって言ってるんだ。その辺どう思う?
A. TypeScriptはいいと思うよ。僕はgoogleに勤めてるけど、Microsoft 製品すごく好きなんだ(Windows Phoneを見せながら)。まぁTypesが必要なシチュエーションが多くなったら僕とかES6決めてるメンバーにフィードバックがほしいなぁ。

Q. 型があったらIDEとかでリファクタリングしやすいと思うんだけど、リファクタリングってどうしてるの?
A. あんまりIDE使ってなくて、僕はsublimeよく使ってるよ。リファクタリングはしたくなった時にしてるかな。テストは型の有無にかかわらず必要なわけだし、型があるからテスト書かなくてよいというわけではないからね。(なんかあんまり噛み合わなかった)

Q. あーじゃああんまりIDEでのリファクタリングの恩恵を受けてないのか。
A. そうだねー。

Q. closure compilerってあるじゃん、あれって型をコメントに書くとチェックしてくれるよね?あの機能ってtraceur-compilerに作らないの?
A. 今のところ予定はないけど、良いアイデアだよね。

Q. closure compilerでES6からES3とかES4とかにトランスパイルする仕組みがあるって噂聞いたんだけどGoogleでは何か動きある?
A. え?そうなの?知らなかった。あんまりclosure compiler詳しくない。

Q. ChromeのES6の対応状況を知りたい。classって3.29に入りそうだよね。
A. まだ入ってないけど多分入るだろうね。

Q. generators/yieldってharmonyオプションはずさないの?
A. あとちょっとで外せるけどまだだね。もうちょっと待ってほしい。

Q. letは?letが一番ES6で使いたい!
A. letも入れたいよねー。今のところ一番よい実装ってIE11なんだよね。Firefoxもあるけどbuggyだし。まぁこれももうちょっとまってよ!

Q. 話せてよかった!今度日本に来る時あったらES6 meetup開くから教えて!!
A. sure!!



dglogic (micorservices in IBM)

Q. microservicesって今後ソフトウェア開発の主流になるかな?
A. 僕らはそう思ってる。あれは、結構基本的な考え方になるんじゃないかな。

Q. microservicesとSOAの違いって分かりにくいよね。
A. SOAってもっと野心的な考え方だけど、microservicesってそんなに大きなことを語っていなくて、単なる大きなサービスを個々のコンポーネントに分割して表現しようって言ってるだけだよね。そこが一番の違いだと思ってる。SOAはどっちかというとユーザー志向でユーザーにとって意味のあるサービスを作る必要があるけど、microservicesって別にそんなに大きなことを語っていなくて、単なる設計手法っていう位置づけだと思ってる。

Q. webアプリケーションとかでも使えるかな?
A. ある程度の規模(7個以上(?)の独立した機能があるサービス)を超えたら使えると思うよ。

nodeconf.eu 1日目 (Future Node.js, microservices, hapi)

さて、 nodeconf.eu に来ています。

当たり前なんだけど、nodeconf.eu ではnode.jsを使っているユーザーが多くて、外人ばっかり。




会う人会う人に「お前の国ではNode.jsは流行ってるのか?」って聞いてるんだけど、とりあえずの理解では、「サンフランシスコ、シアトルとかアメリカでは流行ってる。Dublin、ロンドンとかのアイルランド、イギリスでもまぁまぁ流行ってる。スウェーデンでは全く流行っていない。」っていう感じ。

日本ではどうなんだ?って聞かれたから「MatzのおかげでRubyがめっちゃ流行ってるよ、Node.jsも一時期流行ったけどRubyほどじゃない、最近だとGoとScalaが流行ってるよ」って応えてる。

ちなみにサンフランシスコだと、Node.jsめっちゃ流行ってて、Goがちょっと前のNode.jsみたくぼちぼち流行ってる、エッジな人たちがRust使い始めてるって言ってて、大体想定通りの話だった。

Keynotes: The State of Node by TJ Fontaine

TJ Fontaineの発表。

Node.jsは広く使われ始めてきた、ツールは正しい使い方があり、Node.jsが向くサービス(Web Application, microservices)ではNode.jsが使われてきている。

それにともなって Node.js には安定性が求められるようになってきている。これからはpatchレベルでの安定も担保する予定だ。
あとはロードバランシングをもっと強化して性能面でも安定させたいと思っている。


終わった後でTJ Fontaine に直接質問してきた。

Q. いつ頃Node.js v0.12 出るの?

A. 今は性能面で安定していないことが一番課題。それさえ解決できたら出そうと思っている、詳しい話はFedor Indutny に聞いてみてほしい。

とのことでした。んじゃあ Indutny どこにいるんだろと思って探したらまだ来てないとのこと。
明日以降に期待。

ちなみに写真とったw


Microservices Track

Microservicesトラックでは、IBMGroupon、CityBank、Paypalの人が「俺たちが思う俺達のmicroservices」の話をしてくれてて、バズワード化しつつあるmicroservicesでどんなことをする必要があるのかを話してた。

特に面白かったのはIBMのトラックで、ツイッターではまとめたけど、
microservices間のcommunicateにAMQPとMQTTを使っているとのことで、かなり疎結合なメッセージングが行われてた。

9 anti-patterns JavaScript

JavaScriptのやっちゃいけない9つのこと。原文の資料があるので参考にしてほしい。


hapi workshop

hapiっていうweb application frameworkの使い方。

$ npm install makemehapi -g

ってやるとmakemehapiコマンドが有効になるので、それを叩くとhapiのチュートリアルが出てくる仕掛けになってる。所謂nodeschool形式。

最初のHello Worldからfile upload, cookie へのセッションストア、template engineとかの使い方を学べてすごくよかった。

終わった後で、hapiの作者にhapiがexpressよりも優れている点はどこなんだ?って聞いてみたところ、

hapiはstream baseのresponseを扱えるんだ。expressはstreamをどこかでぶった切る事(多分、body-parser)がある、streamを透過的に扱えるし、expressよりも層が薄いんだ。

とのことでした。

hapiも良かったけど、hapiシリーズのjoiっていうvalidation libraryがあって、それがすごく便利だった。

懇親会会場にて

色々聞いてきた。

Ben (hapi.js author) への質問

Q. hapiもよかったけど、Joi(validation library)が良かった。joiってexpressとかkoaでも使えるの?
A. 使えるよ。express-joiとかkoa-joiってのがあるよ。

Q. hapiのWorkShopとか開くから、日本に来ることが有ったら教えてよ!
A. sure! sure!

substackへの質問

Q. browserifyって今みたいなモジュールローダーとしての使い方は予期してたの?

A. もちろん予期してたよ。ユースケースの一つだろうと最初から思ってた。
僕がやりたかったのは、browserifyでサーバーとクライアントでコードを共有することはもちろん、npmを使ってクライアント側のモジュールを管理したかったんだ。必然的にモジュールローダーの機能も必要になるよね。

Q. そっちの機能(モジュールローダー)の方が主流になることも?
A. まぁ当然あり得るだろうと思ってたよ。予想外という事ではなかった。

Q. いつコード書いてるの?
A. "whenever"

Q. tapeっていうテストモジュールいいよね。でもmochaだとshould.jsとかexpect.jsとか
自分の好きなアサーションモジュール組み込めるけど、tapeだとt.assertに依存してて使えないよね。
A. tapeとmochaはあんまり一緒にしてほしくない。僕はあまりmochaが好きじゃなくて、tapeのがシンプルで好きなんだ。

Q. 日本に来たら何話すの?
A. 決めてない。

このインタビュー終わったら絵を描き始めたので撮影させてもらった。


mikealへの質問

Q. 日本に来たら何話すの?
A. 何かモジュールのこととか、何か話すよ。requestとかかも。

Q. なんか注目している技術はある?
A. 実は最近あまりコードを書いてないんだよね。コミュニティの運営ばかりしてるよ。

Q. nodeconfとか大変だったんじゃない?
A. そりゃまぁ大変だけど、やりがいあるからね。

mikeal, cianと一緒にパチリ


Bert Belder (libuv)への質問

Q. libuv パーカーかっこいい!!
A. インターネットで売ってるぜ!

Q. いつごろ libuv って v1.0 リリースするの?
A. 多分今週末くらいかなー。

Q. libuvのロードマップって何か考えてる?
A. まずは設計のリファクタリングかな~、結構フロストレーション溜まってるんだよね。
全然unixの考え方にそって無くて、もう少しunixっぽいシンプルなデザインにしたい。統一的なAPI呼び出しとか考えてる。
それが終わったら、libuvのスケジューリングアルゴリズムをもう少し見直したい。
libuvのスケジューリングって今は完全に統一されてるんだけどもっと細かいタイミングでスケジューリングできるようにしたいんだ。
あと最近だとRustがlibuv使ってるからnode.jsだけじゃなくてRustの要望も取り入れて行きたい。

Q. libuvのAPIってv1.0が出たらstableになるの?
A. もちろん!

Q. libuvがpure にシステムコール呼ぶよりも遅いっていう話出てるけど。
A. まぁそうなるだろうね。システムに特化した最適化よりも広い環境で使えることを目指しているから。そしてそのときに多少遅くてもその遅延がそこまで問題になることは少ないんじゃないかと僕達は思ってる。どっちかというと広く使えることを目指した結果、多少性能に影響が出てしまうとは思う。

Q. 日本でlibuv meetupとか開きたいけど、もし良かったら日本に来てよ!
A. sure! 11月にある学園祭に行けたらいくよー!

まとめ

  • microservicesの話が面白かった。結構突っ込んで聞けたし、日本での話も需要がありそうなので、どこかでまとめて話したいです。
  • hapiも良かったけど、Joiも良かった。
  • substackとかmikeal, bert belderと話ができてよかった!

こんな感じ :D

海外エンジニアに聞いてみたい質問があれば受け付けるので、twitterとかにメンションください!!

consoleを簡単に色付けするモジュールのcoloを作った

coloを作りました。

coloとは

console.logとかを簡単に色付けできるモジュールです。下記のような書き方で色付けできます。

var colo = require("colo");

console.log(colo.red("colo colo"));
console.log(colo.cyan.bold("colo colo"));
console.log(colo.green.underline("colo colo"));
console.log(colo.magenta.italic("colo colo"));
console.log(colo.grey.inverse("colo colo"));

f:id:yosuke_furukawa:20140904093333p:plain

install 方法

$ npm install colo

作った動機

コンソールの文字列を赤くしたり、緑にしたりするのをよくやってたんですけど、これまでこんな感じでやってました。

//コンソール赤くする:
console.log('\033[31m' + 'Hello World'+ '\033[39m');

//コンソール黄色くする:
console.log('\033[33m'+ 'Hello World'+  '\033[39m');

//コンソール青色にする:
console.log('\033[36m' + 'Hello World' + '\033[39m');

//コンソール灰色にする:
console.log('\033[90m' + 'Hello World' + '\033[39m');

//コンソール緑色にする:
console.log('\033[32m ' + 'Hello World'+ ' \033[39m');

この「\033[32m 〜 \033[39m」が覚えられなくなってきたので、ここまでたくさんやるならちゃんとモジュール化しておこうと思ったのがきっかけです。

※ あと一応、\033はOctal literalsなので、"use strict"の下では怒られます。

こだわったところ

colorizeモジュールは既にいくつも存在するんですが、Stringのprototype拡張してたり、依存モジュールが多かったり、文字列の中で独自の構文を覚えないといけなかったりするのでもう少し手軽なやつを、、、と思って作りました。


依存モジュールを減らしたかったんですが、AnsiColorの定義はコード内に持ちたくないなぁと思ってたらコアのutilモジュールが持ってたので、それだけに依存するようにしました。

DSLライクに

書き味として

colo.red("RED");
colo.red.bold("RED and BOLD");
colo.red.bold.underline("RED and BOLD and UNDERLINE");

みたいにプロパティアクセスっぽく書くんだけど、実際にはメソッドチェーンになるようにdefinePropertyでgetterを持つオブジェクトをネストさせて作っています。

どうやって実現しているかは github を見てもらえるとわかりやすいと思います。

yosuke-furukawa/colo · GitHub

もしバグがあれば教えて下さい!

追記: 9/15

coloをブラウザでも使えるようにして、bowerに公開しました。

<script type='text/javascript' src="./colo/colo.js"></script>
<script type='text/javascript'>
colog(colo.red("colo colo"));
colog(colo.cyan.bold("colo colo"));
colog(colo.green.underline("colo colo"));
colog(colo.magenta.italic.bold("colo colo"));
colog(colo.grey.bold.italic.underline("colo colo"));
</script>

Node.jsで同期的にコマンドを実行できるようにする execsyncs を作った。

Node.jsでshellのコマンドを実行する場合は以下のようにする必要がありました。

var exec = require('child_process').exec,
    child;

//child_process.exec関数を利用する
child = exec('cat *.js bad_file | wc -l',
  // exec関数は非同期関数なのでcallbackを取り、そこでstdout, stderrを取る
  function (error, stdout, stderr) {
    console.log('stdout: ' + stdout);
    console.log('stderr: ' + stderr);
    if (error !== null) {
      console.log('exec error: ' + error);
    }
});

Node.js の v0.11では同期的にコマンドを実行するexecSyncと呼ばれるメソッドがcoreモジュールから提供される事になっています。

これを使うと、同期的に実行するシーンでは以下のように書くことができます。

var execSync = require('child_process').execSync;

//child_process.execSync関数を利用する
var result = "" + execSync('cat *.js bad_file | wc -l');
console.log(result);

こうやって書きたいんですが、Node.js v0.11 からの新機能なので、2014年の7月時点での安定版であるNode.js v0.10では使えません。

そこで v0.10でも v0.11でもexecSyncを使えるようにするライブラリ、execsyncsを作りました

また、v0.12が出たとしてもすぐに移行できるわけではなく、しばらくv0.10とv0.12の両サポート体制は続くと思うので、同期的にコマンドを実行させたい場合は今からでもこのexecsyncsを使っていても良いかと思います。

使い方

インストールはnpmでサクッと。

$ npm install execsyncs

使い方は簡単で、さっきのchild_processのところをrequire('execsyncs')に変えるだけです。

//execsyncsをrequireする
var execsyncs = require('execsyncs');

var result = "" + execsyncs('cat *.js bad_file | wc -l');
console.log(result);

作ってみて思いましたがv0.10でもv0.11でも使えるし、割りと便利なので、gruntとかgulpみたいなタスクランナー系でも活躍しそうだなと思ってプラグインも作っておきました

スクランナー系

スクランナー使っても簡単なコマンドの即時実行としては使えますが、実行結果のstdoutを拾って結果をどうこうするとかそういう事がしたいのであれば、タスクの中で直接execsyncsを使ってください。

実現方法

基本的にはhecomiさんが作ってくれてたexecsyncをv0.11でもコンパイルできるようにNANで加工して、後はchild_process.execSyncメソッドの有無を調べて有ったらコアモジュール側を利用し、無かったらコンパイルした奴を利用しているだけです。

細かい実現方法に関してはgithubを一読ください


バグとか有ったら気軽に報告してください!!

Enjoy sync programming :) !!

Farewell Node.js (翻訳)

「visionmedia、Node.js辞めるってよ」って事で、今回はこの話の翻訳ですね。

Farewell Node.js — Code adventures — Medium

最近のnode.jsはホントTJ Fontaine のリーダー就任から始まってNode.jsでできたエディタであるAtomがreleaseされたり、gemのモジュール数をnpmのモジュール数が抜いたり、socket.io v1.0が出たりと色々あるんですが、今回の話は飛び抜けて衝撃的だったなぁと思ってます。

一応知らない方のためにvisionmediaについて説明しておくと、以下のモジュールは全てvisionmedia製です。

  • express (Web Applicaiton Framework)
  • mocha (Testing Framework)
  • jade (hamlライクなtemplate engine)
  • stylus (meta css)
  • component (フロントエンドのパッケージマネージャ)
  • koa (Web Application Framework)
  • co (yieldをwrapしたフローマネージャ)
  • commander (CLI作成ツール)

これらのライブラリは一度は聞いたことあるんじゃないでしょうか。
彼はnode.jsの初期からNode.jsのライブラリやツールを作り続けていて、Node.jsコミュニティに多大な貢献をしています。彼の動きというのはnode.jsの業界だけじゃなく、Web業界に大きな影響を与えています。
そんな彼がなんでNode.jsを去るのか、翻訳してみたので最後まで読んでみてください。

さようなら Node.js

node.js landから僕は去ります

僕は今日まで、Node.jsとproductionにおいて長い間戦ってきた。そして不幸なことにこれ以上楽しめなくなってきてしまった、少なくともこのメッセージを最後に公式な別れの挨拶とさせてもらう!あと重要なことだけど、僕のライブラリをメンテしてくれるメンテナーを募集してます!

Nodeはうまく物事を進められる、だけど突き詰めた結果、最近の僕が惹かれるソフトウェアにとっては正しいツールではなくなってしまった。僕はまだNodeをweb siteで使うことを計画しているけど、もし誰かがメンテナーになってくれるなら是非僕に教えて欲しい。あなたのGitHubアカウントとnpmユーザー名を書いて送ってくれ!僕が求めるのは既存のAPIのドラスティックな変更をしないでほしいってことだけだ、もしドラスティックな変更をするなら新しいプロジェクトを始めてくれたほうがマシだろう☺。

Koaは僕がメンテするプロジェクトの一つにはなるだろう、もちろんcoとその他のkoaフレンド達もだ。

聖杯 (The Holy Grail)

僕はCがずっと好きだった、だけどCで仕事する人はやりがいがある事もエラー起こしがちな事も両方知っている。C言語で作業することが最速だって確実に言えない限り、日々の作業においてC言語の選択を正当化するのは大変だ。C言語のシンプルであることを僕は常に賞賛してきた、しかし巨大な量のboilerplate無しで成長することは出来ないだろう。

分散システムで作業をすればするほど、使いやすさやロバスト性よりもパフォーマンスを好むNodeの方向性に対してフラストレーションが溜まってきたんだ。一週間くらい前から僕はGoで大きな分散システムを書きなおしてみた、そしたらどうだ、ロバストもパフォーマンスも改善され、そしてメンテナンスも簡単になった、それだけじゃなくてテストカバレッジもよくなった、それ以来ずっと同期的なコードがより素晴らしくシンプルに成立している。

僕はGoが聖杯(The Holy Grail)だって言ってるんじゃない、完全じゃないところもある、だけど今日までに存在している数ある言語の中でGoは僕にとってはすばらしいソリューションだったんだ。RustやJuliaといった"次世代の"言語は活用する場所が見つかり、成熟すればさらに素晴らしいソリューションになるだろうと確信している。

個人的には、Goに対して最も興奮したのはその開発スピードだ、彼らがしきりに2.0にしたがっているのを見るとワクワクするし、彼らは既に存在するものを壊し始めることに抵抗が殆ど無いんだ、素晴らしいことだよ。

修正:いくつかのMLにポストされた内容を誤解してたみたいだ、彼らは別にbreaking changesをしようとしているわけじゃないみたいだ。

これが真実だったなら良かったのに、もし言語から利益を得るなら僕は素早くものを壊す事が良いことだと信じているから。だけど僕は巨大で動作中の重たいシステムを作っているわけじゃないからね :D

なぜGoなのか?

Nodeは今でも良いツールだし、もしあなたにとってうまくいっているならそのことに対して心配することは何もないよ、でももしNodeがあなたを困らせているなら、そこから出て、他の手段を見つけるのを忘れちゃいけない。(プロダクトに対してGoを使って数時間作業してみたら僕はもう夢中になってたよ。)

もう一回言うけど、僕は決して「Goが完璧に良い言語だ」、「絶対に使った方がいい」、なんて事は言ってない、年齢の割に成熟しててロバストだからだ(大体Nodeと同じくらいの年齢だ)、型によるリファクタリングは楽しくてシンプルだし、Goのツールはプロファイルやデバッグするには素晴らしい、さらにコミュニティは強力な規約、豊富なドキュメント、フォーマッタ、ベンチマークAPI設計を持っている。

最初にGoを聞いた時、Goの標準ライブラリのいくつかは酷いものだと思った、Nodeの中にある極端なモジュール性に慣れすぎていたり、Rubyの腐った(過去の)標準ライブラリの経験をしてたからだ。Go言語に関わった後では標準ライブラリのほとんどが今日プログラミングをするために必要な(圧縮, json, IO, バッファリングされたIO, 文字列操作といった)本質的なものだという事がわかった。これらのAPIのまとまりはよく定義されていて強力だ。標準ライブラリを消費するだけで全体のプログラムを書きあげることができて、しかも非常に簡単だ。

3rd party Go packages

ほとんどのGoのライブラリはlook & feelが似ている、僕がこれまで見てきた3rd partyのコードのほとんどはこれまでのところ高品質だ。JavaScriptはスキルレベルの範囲が広いため、Nodeで良いライブラリを見つけるのは難しい。

Goのパッケージには中心となるレジストリは存在しない、だから同じ名前のパッケージが5個も6個も見つかる時がある。そういった時には混乱することもある。そのため、一番良いソリューションを決めるためにそれぞれ中身を読み込むことになるだろう。Nodeでは既に認められてるパッケージがある、例えば"redis", "mongodb-native", "zeromq"といったように、だからあなたはそれが一番良いものだと仮定して(中身を読むことなく、)その場所で立ち止まってしまうかもしれない。

Go vs Node

もしあなたが分散を仕事としているなら、Goの表現豊かな並行性がとても使いやすいって事がわかるだろう。僕らはNodeで似たような事を実現しようとして、generatorsをNodeで持ってきた、だけど僕の意見ではgeneratorsはGoの半分くらいしか方法を提供していないように見えるんだ。エラーハンドリングとエラーリポーティングを分割しないって事は贔屓目に見ても二流の解決策だと思う。より良いソリューションを知っていながら、僕はコミュニティが最適化するのに3年とか待ちたくなかった。

個人的な意見だけど、Goでのエラーハンドリングは優れているよ。Nodeは全てのエラーややっていることの判断に対して考えないといけないけど、そういうセンスを持っていれば素晴らしいと思う。だけどNodeの以下の様なやり方は失敗していると思う。

例えば:

  • 冗長なcallbackが必要になる
  • callbackを全くとらない事もできる (その場合は失われる)
  • 責任範囲外のエラーも取れる
  • "error" イベントで複数のエラーを取ることができてしまう
  • "error" イベントを取らないと全ての事が地獄に落ちる
  • "error" ハンドラを要求するかどうかが不確実
  • "error" ハンドラがとてもあいまい
  • callbacksがクソ

Goでは僕のcodeが実行された時には中ではそれが既に起こっていて、そのステートメントを(別のライブラリから)再実行することはできない。
Nodeでは違う、ルーチンが完全に終了されるまで、突然あるライブラリが複数回僕が設定したcallbackを実行する事もあればhandlerがclearされずにコードの再実行を引き起こす事だってある。

こういうのってliveのproduction codeに対して何が起きてるのか推測していくのが信じられないくらい難しいんだよね。なんでそんなことに悩んでたんだ? 他の言語ではこの痛みを経験する事は無いんだぜ。

Nodeの未来へ

僕はNodeが今後もうまくやってくれるってことに期待してる、たくさんの人々がNode.jsに投資してて、しかもポテンシャルを持ってる。ただ僕はJoyentやコア開発チームがユーザビリティにフォーカスする必要があるなと思ってる、パフォーマンスはアプリケーションが小さいならあまり意味が無いし、デバッグ、リファクタ、開発はまだ難しいと思っている。

実際に4-5年間、僕らは "Error: getaddrinfo EADDRINFO" みたいな曖昧なエラーを受け取ってきた。当たり前の事だけど、システムのコアをエンハンスするのに集中してると、こういうミスを起こしやすい、何度も何度もこんなようなことをユーザーは表現してきたけど(良くなった)結果を見たことがない。

Streamは壊れてて、callbacksはいい方法じゃないし、エラーは曖昧だし、ツールも良くない、コミュニティの規約のようなものはある、しかしGoと比べると何か欠けてるように感じてしまうんだ。web サイトやAPIやプロトタイプを作るとか、そういうタスクがあるなら僕はNodeをまだ使うだろう。もしNodeがこれらの基礎的な問題を解決してくれるなら残ってる適切な自身の問題を解決するチャンスだと思う。ほかの解決策がより良いパフォーマンスとより良いユーザーフレンドリーを持ってきてくれるんだったら、ユーザビリティとパフォーマンスによる議論は飛ばなくなるだろう。

これは個人的な誰かを攻めているわけじゃない、たくさんの本当に才能ある人達とNodeで一緒に仕事してきて、それでも僕はもう興味を持てなくなったっていうただそれだけの事なんだ。そのコミュニティの一部としてすごく有用な時間を過ごしてきた、そしてマジでcoolな人たちにもたくさんあってきた。

この話の教訓は、あなた自身の小さな思いを滞らせちゃいけないってことだ! 他のものも見ようぜ、あなたがもう一度プログラミングを楽しむことができるかもしれない。たくさんのイケてるソリューションがそこにはあるし、僕の間違いはそういう他のソリューションを試してみるのを待ちすぎてたって事だ☺。

感想

visionmediaの話はここまでで、ここからは僕からの個人的な感想です。

まず、この話が出た時にみんな色んな反応してて、一番多かったのはexpressとかmochaとかどうなるの?ってことでした。
一応答えておくと、もうすでにExpressもmochaもvisionmediaは積極的なメンテは行っておらず、別な人がメンテナとして活動してます。

componentもjadeもstylusも別な人が積極的にメンテしてます。なので、一応言っておくと既に使っているライブラリがメンテされるかどうかはvisionmediaの去就とは無関係ですね。

彼はゼロから使いやすくて革新的なライブラリ、ツールを作るのが得意な人物ですが、たくさんライブラリ、ツールを作りすぎててメンテナンスはあまり得意じゃないです。なので、ある程度まで大きくなるとどっか行ってしまう傾向があります。その代わりちゃんと別なメンテナを立ててくれるので、ヘビーに使われてるライブラリに関しては新しいメンテナが面倒を見ることでしょう。

visionmediaの言葉にもあったけど、visionmediaは最近分散システムでの仕事をSegment.ioってところでやってます。

これまではLearnBoostやCloudUpってところでWebアプリケーションを高速に作れるようにするのが彼の仕事でした。その結果生まれたのがexpress, mocha, stylus, jadeでしょう。

Segment.ioっていう会社はGoogleAnaylticsとかmixpanelとかの解析ツールを統合するツールを作ってる会社で、環境が変わるとやっていることは変わるしそれに対して別なソリューションが必要になってくるというのが非常によくわかります。

そして少し前の彼がNode.jsでかなり攻めてるツールを作ってて、

  • yal (Yet Another Logger, 分散環境でも使えるfluentd ライクなロギングライブラリ)
  • punt (UDPでメッセージングを行うライブラリ)
  • node-actorify (TCPでactorライクにメッセージングを行うライブラリ)

こんな感じで分散システムでの仕事を中心にしていることがわかります。
正直なんでこんなの作ってんだろって思ってたんですが、やっぱりSegment.ioで必要なツールを作ってるんでしょう。
なので分散環境でNode.jsを使って戦えるツールを作っていたんでしょうが、Goという新しいソリューションに惹かれてやってみたらものすごく良かったという事だと思います。

彼のようなコミュニティに多大な影響を与えてくれる優秀なエンジニアには一つのところにとどまっていてほしくないので、僕としては彼がGoで起こすであろうたくさんのイノベーションが楽しみです。
あと、socket.io meetupでGuillermoとNode学園祭の話をしてたら、TJ FontaineとTJ Hallowaychuk(visionmedia)の2人でNode vs Goのディスカッションさせるとかマジで熱くない??とか言われたんで、二人共日本に来てくれるかかなり怪しいんですがアプローチだけはかけてみたいと思います。

大阪のNode.js勉強会でNode.jsのセキュリティについての話してきた #npp02

大阪Node学園に行ってきました。

かねてから雰囲気を知りたいと思っていた大阪Node学園に行ってきました。

行く前から今回の勉強会はすごく人数が少ない、という事だったので、役に立つ話(セキュリティの話)とぶっちゃけ話(心の闇)の両方をしようと思って行ってきました

建前と本音の話

建前と本音というタイトルで話してきました。

建前編はセキュリティに関する話がメインで、そんなにNode.js関係ないんですがProductionで動かすなら知っておいてまぁ損はないです。
本音編は本音というかセキュリティに関するぶっちゃけ話なので言えない事が多く、削除してしまいました。


大阪Node学園の発表内容

「Node を稼働させる」 by @kumatch

資料 :

Node.jsを本番環境で起動させるには、っていうことで、プロセスをデーモン化させたり初期起動で動作させるために必要なツールの話だった。
foreverからinit.d、upstart + monitを経て、pm2に至るまでの話で、実際にはpm2の機能紹介がメインって感じだった。

pm2かなり便利で、勝手にworker processを起動してくれる、いわゆるserver starter 的な機能があるって知らなかった。
内部的にcluster化してくれるっぽく、非常に便利。

「Scalable Node.js with Redis Store」 by @kamiyam

資料:

Socket.ioのクラスタリングをやるときの話で、RedisStoreを使った際の話でした。
DEMOを効果的に使ってて非常にわかりやすかったです。
Socket.io v1.0 の話ではなく、v0.9でしたが、v1.0でも基本的なノリは同じで若干使うライブラリが違うだけなので、聞いてる方々は勉強になったと思います。

Socket.ioに興味を持たれた方は 6/23にやる東京Node学園と7/3にやるsocket.io-meetupの話両方聞くと今起きている事がわかると思います。

「本番環境のロギングやモニタリング」 by @leichtgewicht

資料 : 上げられておらず??

本番環境のロギング、モニタリングということでfluentd + datadogでログ収集と可視化する話でした。
datadog知らなくて、手軽で面白そうだなーと思いました。

弊社fluentdコミッタからは以下の様なコメント

ということなので、非常に有力かと。NewRelicとかは使ったことあったけど、既にfluentdとかでログを取ってる場合はDataDogもいいかなーと思いました。

「BeerBashとLT大会と矢谷重人のすべらない話2」 by @vanx2

みんなでピザ、ビール、お菓子をつまみながらのLT大会でした。

@leichtgewicht こと、マーティンが社内で使ってるexpress拡張の話と
@yosuke_furukawa による JSON5とstubcellのステマと、QuizNowのステルスじゃないマーケティングの話、
@kamiyamによるsails.jsの解説だった。

どの話も面白かった。

感想

知らないこと多くて、すごく有用だったなーと思いました。
特に

  • pm2
  • sails.js
  • datadog

あたりの話はすごく面白かったです。

あんまり大阪の地理に詳しくなかったんですが、最後みんなが途中まで送ってくれてありがたかった。
また大阪行きます!あと、東京にも来てください!!

Unix Philosophy と Node.jsのモジュールの作り方

The Art of UNIX Programming

The Art of UNIX Programming

TL;DR

  • Unix Philosophyにおいては、「一つのことをうまくやり、協調する仕組みを持つ」という事が大事
  • Node.jsのモジュールにおいても同じで、「一つのことをうまくやる、Stream APIで協調する」と良い
  • 「一つのことをうまくやる」にはどうするのが良いのか、ということで substack のモジュール実装例
  • Simple と Easyの違い

ちょっと今回長くて文字が多いので、最初と最後にまとめを用意しました。時間がない方はこれを読むだけでもいいかと。

Unix Philosophy

さてさて、Unix Philosophyという考え方があることを知っているでしょうか。

ソフトウェアにおける普遍的な哲学の一つで、「一つのことをうまくやれ」と略される事が多いです。wikipediaからの説明を借りる

これがUNIXの哲学である。
一つのことを行い、またそれをうまくやるプログラムを書け。
協調して動くプログラムを書け。
標準入出力を扱うプログラムを書け。標準入出力は普遍的インターフェースなのだ。

— M. D. マキルロイ、UNIXの四半世紀

というものです。

これはサマリとして紹介されるものなので、すべての考え方を学びたいのであれば、The Art Of Unixを読むことをオススメします。

この考え方はソフトウェアを設計する際の考え方に留まらず、色んな分野に応用できる非常に重要な考え方です。Simpleを徹底的に追求し、責任範囲を分割して制限する、という考え方は何においても応用できます。

Unix Philosophyの説明をさらにX-Windowsシステムを作ったMike Gancarzが9つのポイントにまとめてます。

  • Small is beautiful.
  • 一つのことをうまくやるプログラムを作る
  • 出来る限り早くプロトタイプを作る
  • 効率よりもポータビリティを選ぶ
  • 単純なテキストファイルにデータを保存する
  • ソフトウェアの効率を開発のアドバンテージに利用する
  • 効率とポータビリティを改善するためにshell scriptを利用する
  • 束縛するUIを避ける
  • すべてのプログラムはフィルタとして振る舞うように作る

Node.jsはこの考え方にかなりインスパイアされています。
Node.jsを作ったRyan Dahl は最後のポイントと非常に似た「すべてのプログラムはプロキシである」という言葉を残してますし、最初の3つのポイントはsubstackがモジュールを作る上で信条としている事です。

そのため、Node.jsのモジュールも原則としてこの考え方に則ると良い、という事が前リーダーであるizaacs から言われています

Unix Philosophyと Node.js

izaacsがまとめたNode.jsのモジュールの書き方を翻訳してみました。かなりUnix Philosophyインスパイアされている事がわかります。

一つのことをうまくやるモジュールを書こう。


古いモジュールに機能を足して複雑化させるよりも新しいモジュールを書こう。


継承よりもcompositionを推奨するモジュールを書こう。


統一的なインタフェースとしてデータを Streams API で扱うモジュールを書こう。


入力元もしくは出力先を意識しなくても扱える(ブラックボックスとして扱う)モジュールを書こう。


あなたが知らないものを学ぶために、あなたが抱えている問題を解決するモジュールを書こう。


小さなモジュールを書こう。素早くイテレーションを回し、容赦なくリファクタリングしよう、勇気を持って書き換えよう。


あなたが必要だと思ったら、即モジュールを書こう、規則に従っていくつかのテストを書こう。


広範囲に渡る仕様は避けよう。


修正したバグにはテストを書こう。


公開するためにモジュールを書こう、たとえそれが個人的な問題解決のためであっても。


ドキュメントをちゃんと書こう、あなたは将来、ドキュメントがあることに感謝するだろう。


=======================================


動くことは完璧を追い求めるよりも良いことである。


集中することは多くの機能があることよりも良いことである。


互換性があることはコードが綺麗である事よりも良いことである。


シンプルであることは何よりも良いことである。

シンプルで一つのことをやるモジュールが良いこと、協調して動作するために統一的なインタフェースがあると良い、ということが書かれています。Stream APIが重要だと言われている理由の一つはここから来ていて、Unixで言う、標準入出力に当たるインタフェースとしてStream APIをデータハンドリングに使うことが推奨されています。

さて、このエントリが公開されたのは2013年で、それ以来、色んなモジュールが影響を受けてきたことは言うまでもありません。

最近だとExpress 4.0がそうです、Express 3.0まででプリセットで用意されていたgeneratorやsession等の機能をモジュールに分割し、シンプルな構造を保つことにしています。また、gruntやyeomanもそうです。Simpleを追い求めて色んなモジュールがプリセットされている状況を作るのではなく、モジュールが分割された状態でユーザーが自分でモジュールを組み込む事を推奨しています。

Stream APIで言えば、gulp は各プラグインがStream APIを通してpipeを使い、協調して動作するように設計されています。
モジュールとアプリケーションでは層が違うので、全てをシンプルに保つのは難しいのですが、ある程度依存性を抑えたシンプルな設計をするという考え方に従っていると思われます。

substack が語るnpmモジュールの作り方

browserifyを作成したsubstackは割りとはじめの方からこの考え方に則ってモジュールを作っています。そんな彼が具体的にどうやってモジュールを書いているのかが公開されています。

実際にSimpleなモジュールを書く上で参考になると思うので翻訳しておきました。

1. 10行くらいのexampleファイルを作ってそこにapiの使い方を最初に書く。



2. exampleファイルによって `require` される index.jsファイル(モジュールの起点となるファイル)を作り、肉付けしてく。


3. index.jsファイルに対して変更を加えていき、example ファイルに対しても変更を追従させる、つまり、変更を反映するために必要に応じてexampleファイルを更新する。



4. exampleが正常に動作するならtest/フォルダにそれをコピーする。


5. npm install tap またはブラウザでもテストする場合は npm install tape を行う。私(substack自身)はシンプルなexampleから適用できるシンプルなテストを好む。


6. example コードの周囲にいくつかのアサーションを追加する。


7. pkginitnpm initを使ってpackage.jsonを生成する。



8. example fileはREADMEにも書く、READMEにあれば、モジュールの使い方を探しやすくなる。


9. READMEの先頭にそのモジュールの宣伝文句、説明文を書き、ライセンスやインストール方法を書いておく。


10. github リポジトリを作る。


11. travisとtestling-ci の設定ファイルを書き、github hookを追加する。



12. git push そして npm publish を行う。

このステップの他にも参照元では巨大なアプリケーションを作りそうになったらなるべく、分割して再利用すること、それが如何にメンテナンスコストを下げられるかが書かれています。exampleコードを10行程度で書く、というある程度の目安があってSimpleを実践する時の参考になると思います。

how I write modules

Simple is not easy

ここまでSimpleさを追求するために色んな事を書いてきました。ここからはSimpleという概念とEasyという概念について説明します。

この前、葉桜JSt_wadaさんがpower-assert作った話をしてくれてて、その中でSimpleとEasyは違うという話をしてくれました。

それの基になった話がシンプルさの必要性についてです。

SimpleとEasyは混同されることが多いです。ただ両者には隔たりがあり、別なレイヤーとして考えた方が設計はうまくいきます。

シンプルさの必要性の話の中で感銘をうけたのは、Simpleは一つの役割を持つ、一つのタスクを実施するといった一次元の考え方であり、客観的である、ということに対してEasyは自分の経験則に近い、とか、自分が抱いている考え方と似ている、といった主観的で相対的な考え方であるという説明です。

つまり客観的に見てSimpleな構造を作ることはできるが、誰にとってもEasyな設計というのはありえないというのが分かります。人によって経験則や考え方が違うため、ある人にとっては簡単でも別な人にとっては簡単ではない可能性があるためです。

Node.jsのweb frameworkによるEasy

ここまでの話はあくまでモジュールの話であってアプリケーションの話ではありません。ちょっと脱線してアプリケーション依りの話でEasyの例を紹介します。

Node.jsのweb frameworkにはfullstackなものと層が薄いものがあるんですが、それぞれEasyのアプローチが異なっています。

層が薄いものとしての代表例は Expressですが、ExpressのアプローチはSimpleを重視して、コアモジュールにはルーティング程度の機能しかなく、Easyのレイヤーは各開発者が自分達でライブラリを取捨選択して実現するというアプローチをとっています。

fullstackのアプローチはこれと全く逆で色んなモジュールやツールがプリセットされているため、学習コストは高くなりますが、一旦経験を積んでしまえば経験則を活かして簡単に作れるというアプローチを取っています。

Expressライクな層の薄いフレームワークとfullstackなフレームワークは根本的に提供するものが異なるので、比較してどっちがいいとか言うものではないです。

層の薄いフレームワークは自分でライブラリを取捨選択し、scaffoldと組み合わせることで、独自のbootstrapを作るのに向いてます、ドメインに特化したフレームワークを作るのであればこっちのほうが良いと言えます。

反対にfullstackフレームワークはその経験則や考え方が近い人達が集まった時に採用すると効果を発揮します、ある程度経験を積んでEasyだと感じる人達がたくさんいれば学習コストも低くて済みます。

ここで言えることは各アプリケーションのレイヤーでは、消費者にとって何がEasyなのかを考えないといけない、一方で各種ライブラリやモジュールに関してはできる限りSimpleでお互いが協調できる仕組みを持っている方が良い、という事が言えます。SimpleとEasyのどちらの層を実現しようとしているのか意識的に設計すると良いでしょう。

まとめ

  • Unix Philosophyにおいては、「一つのことをうまくやり、協調する仕組みを持つ」という事が大事だと言われていました。
  • Node.jsのモジュールにおいても同じで、「一つのことをうまくやる、Stream APIで協調する」というモジュール開発指針が出ています。
  • 「一つのことをうまくやる」にはどうするのが良いのか、ということで substack のモジュール実装例を上げました。
  • Simple と Easyの違い、設計においてはどちらを実現しようとしているのか意識したほうが良いということを説明しました。