小林 (koichik) です.

なぜ初心者には見えない人達が盛り上がってるのか
小一時間(ry

ともあれ (JW)、翻訳書からのサンプルなので、
時期的に原書が v0.10 に対応しているはずがなく、
ここでは Stream1 の話ということにした方が
いいんじゃないかと思いますけれど。

> てことで、「fs.stat() も open イベント内部に押し込むと、意図した順序で処理してくれる。」てのが課題に対する私の解答。

んー、自分が想定 (期待) したのと違う問題を
解決しようとしてるようなw

fs.stat() を 'open' イベントリスナの中に押し込むと、
fs.stat() のコールバックが呼び出されるタイミングは
元のコードよりさらに遅くなりますよね。

すると、キャッシュのバッファを埋めるための 'data'
イベントのリスナを登録するのもさらに遅くなりますね。
それで大丈夫でしょうか?

たとえば極端な例として、

var s = fs.createReadStream(f).once('open', function() {
  response.writeHead(200, headers);
  this.pipe(response);
});

setTimeout(function() {
  s.on('data', function(buf) {...});
}, 10 * 1000); // 10 秒!!!!

だったらどうでしょうか?
setTimeout() の中で登録した 'data' リスナは
適切に呼び出されるでしょうか?


On Tue, 16 Apr 2013 08:11:48 +0900, Akitoshi Manabe <[email protected]> 
wrote:

> 眞鍋です。
> 
> スミマセン。誤解してました。
> 以下のファイルを書いて試したところ、fs.createReadStream だと
> readable イベントは発火しませんでした。
> 
> ---- (ここから)
> var util = require('util');
> var fs = require('fs');
> var f = __filename;
> 
> var s = fs.createReadStream(f, {bufferSize: 128 }); // default : 64 * 1024
> [byte]
> s.on( 'readable', function(){ util.puts( 'readable', arguments ) } );//発火せず
> s.on( 'open', function(){
>     util.puts( 'open', arguments )
>     // data イベントはopen後でも追加できる。
>     s.on('data', function( d ){ util.puts('DATA ', d) })
> } );
> s.on( 'error', function(){ util.puts( 'error', arguments ) } );
> s.on( 'close', function(){ util.puts( 'close', arguments ) } );
> ---- (ここまで)
> 
> 実は、readable イベントに押し込めるのではないかと考えていましたが、
> 「data イベントは open 直後に実行されるハンドラ内に定義しても良い」と確認できます。
> てことで、「fs.stat() も open イベント内部に押し込むと、意図した順序で処理してくれる。」てのが課題に対する私の解答。
> 
> 
> Nodeを始めた頃「関数のネスト(ピラミッドとも)で書く特徴」に悩まされました。
> 理解が深まってくると、ピラミッドをフラットで見やすく書く為の
> 「フロー制御」を考えたくなると思います。
> 
> 
> 
> 
> 2013年4月16日 7:08 aporo4000 <[email protected]>:
> 
> > 全然違うかもしれませんが、最初に読み込むバイト数を指定するとか!?ですか?
> >
> > 2013年4月16日火曜日 1時20分00秒 UTC+9 koichik:
> >>
> >> 小林 (koichik) です.
> >>
> >> 勝手に課題シリーズ第二弾w
> >> 前のメールでも書いたように、非同期 API では
> >>
> >> ...   //(1)
> >> foo(hoge, function(err) {
> >>   ... //(2)
> >> });
> >> ...   //(3)
> >>
> >> の場合の処理順は (1)->(3)->(2) となります。
> >>
> >> 問題のコードは HTTP を処理するリスナの中に
> >> あるので、
> >>
> >> http.createServer(function(req, res) {
> >>   ...   //(1)
> >>   foo(hoge, function(err) {
> >>     ... //(2)
> >>   });
> >>   ...   //(3)
> >> });
> >>
> >> となるわけですが、ここで二つの HTTP リクエスト、
> >> A と B がほとんど同時に (ただし A が先に) 到着した
> >> 場合の処理順を考えてみましょう。
> >>
> >> その場合は、
> >> A(1)->A(3)->A(2)->B(1)->B(3)->B(2) となる。。。
> >> 保証はなくて、
> >>
> >> A(1)->A(3)->B(1)->B(3)->A(2)->B(2) だったり
> >> A(1)->A(3)->B(1)->B(3)->B(2)->A(2) だったり
> >> する可能性もあります。
> >> リクエスト A に関する処理が全て完了してから
> >> リクエスト B の処理が開始されるとは限らない
> >> わけです。
> >>
> >> さて、問題のコードからキャッシュの処理に着目すると、
> >>
> >> http.createServer(function (request, response) {
> >>     //(1)
> >>     if(cache[f]) {
> >>         response.writeHead(200, headers);
> >>         response.end(cache[f].content);
> >>         return;
> >>     }
> >>
> >>     fs.stat(f, function(err, stats) {
> >>         //(2)
> >>         var bufferOffset = 0;
> >>         cache[f] = {content: new Buffer(stats.size)};
> >>         s.on('data', function(data) {
> >>            //(3)
> >>            data.copy(cache[f].content, bufferOffset);
> >>            bufferOffset += data.length;
> >>         });
> >>     });
> >> }).listen(8080);
> >>
> >> という構造を抽出できるのですが、最初に到着した
> >> リクエスト A の処理では、
> >>
> >> (1) キャッシュが存在しないことを確認し、
> >> (2) キャッシュを作成して fs.stat() を呼び出し、
> >> (3) 'data' イベントが発生するとキャッシュの中身を設定
> >>
> >> と流れていくことはもう理解できているかと思います。
> >>
> >> では、この途中のどこかで別のリクエスト B が到着すると
> >> どうなるでしょうか?
> >>
> >> A(1)->A(2)->A(3)
> >>
> >> と進む途中のどこかで、リクエスト B の処理が
> >> 挟まってきた場合を考えてみましょう。
> >>
> >> A(1)->B(1)->?
> >>
> >> とか、
> >>
> >> A(1)->A(2)->B(1)->?
> >>
> >> とか、タイミングによっては B の処理が進む経路も
> >> 変わってくるはずですね。
> >>
> >> 掲載されたコードはどんな場合でも正しく
> >> 動作するでしょうか?
> >> うまくいかないのはどんな場合?
> >> どんな場合でもうまく動くようにするに
> >> どうしたらいいでしょうか?
> >>
> >>
> >> On Mon, 15 Apr 2013 06:18:31 -0700 (PDT), aporo4000 <[email protected]>
> >> wrote:
> >>
> >> > いまちょうどそれを勉強してる初心者なので、みなさんみたいにスラスラ書いたり出来るように頑張ります!
> >> >
> >> > --
> >> >
> >> > ---
> >> > このメールは Google グループのグループ「Node.js 日本ユーザグループ」の登録者に送られています。
> >> > このグループから退会し、メールの受信を停止するには、[email protected]にメールを送信します。
> >> > その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。
> >> >
> >>
> >>
> >> --
> >> {
> >>   name: "Koichi Kobayashi",
> >>   mail: "[email protected]",
> >>   blog: "http://d.hatena.ne.jp/koichik/";,
> >>   twitter: "@koichik"
> >> }
> >>
> >>  --
> >
> > ---
> > このメールは Google グループのグループ「Node.js 日本ユーザグループ」の登録者に送られています。
> > このグループから退会し、メールの受信を停止するには、[email protected]にメールを送信します。
> > その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。
> >
> >
> >
> 
> -- 
> 
> --- 
> このメールは Google グループのグループ「Node.js 日本ユーザグループ」の登録者に送られています。
> このグループから退会し、メールの受信を停止するには、[email protected] にメールを送信します。
> その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。
> 
> 


-- 
{
  name: "Koichi Kobayashi",
  mail: "[email protected]",
  blog: "http://d.hatena.ne.jp/koichik/";,
  twitter: "@koichik"
}

-- 

--- 
このメールは Google グループのグループ「Node.js 日本ユーザグループ」の登録者に送られています。
このグループから退会し、メールの受信を停止するには、[email protected] にメールを送信します。
その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。


メールによる返信