stream between nodejs and whatwg

1ff811939fd0923df8321ec6d8bf9d4b?s=47 Jxck
August 08, 2016

stream between nodejs and whatwg

Talk about Stream API difference between node.js and whatwg
at #tng11 2016/08/08

1ff811939fd0923df8321ec6d8bf9d4b?s=128

Jxck

August 08, 2016
Tweet

Transcript

  1. Stream b/w node.js & whatwg Tokyo Node Gakuen #tng22 2016/8/8

    Jxck
  2. • id: Jxck • github: Jxck • twitter: @jxck_ •

    blog: https://blog.jxck.io • podcast: http://mozaic.fm • Love: music Jack
  3. mozaic.fm ep10 Node.js 3 https://mozaic.fm/episodes/10/nodejs.html

  4. 4 Node.js の Stream API で「データの流れ」を扱う方法 - Block Rockin’ Codes

  5. “Stream を制す者は Node を制す” 5

  6. “Stream を制す者は Node を制す” 6 から 5 年...

  7. 7 WHATWG Streams Stream API がブラウザにやってくる - Block Rockin’ Codes

  8. 先に結論 8 互換性など無い

  9. Stream とは?(哲学) 9

  10. Common Terminology 10

  11. 11 概念としての Stream File Process Network File Process Network Without

    Stream(データをまとめて次に渡す) With Stream(データを得られた順に次に渡す) then(buffer) pipe(chunk) then(buffer) pipe(chunk)
  12. 12 両者の供述を聞く

  13. • 非同期は Callback が基本 • 引数にルールを決めて扱いやすくしよう • 連続するイベントは EventEmitter •

    EventEmitte の上位 API が Stream • Multi-Consumer • カスタマイズは継承 13 In Node.js Stream data data data data data data data data data data data data
  14. 14 In WHATWG • 非同期は Promise を返してこう • Async/Await でそれを便利にしよう

    • もちろん Stream は Promise のジェネレータ • (≠ ES6 Generator) • Single-Consumer • カスタマイズはコンストラクタ Stream Promise
  15. diff of Basic Async Handling 15 // Node.js - Callback

    file.readFile(path, (error, data) => { console.log(error, data); }); // WHATWG(@2016) - Promise cache.match(req).then((res) => { console.log(res); }).catch((error) => { console.error(errror); });
  16. node.js stream // ReadableStream extends Stream (extends EventEmitter) readableStream.on(‘data’, (value)

    => { console.log(value); }); readableStream.on(‘end’, () => { console.log(‘done’); }); readableStream.on(‘error’, (error) => { console.error(error); }); 16
  17. whatwg stream let reader = readableStream.getReader(); // read() を呼ぶと chunk

    を resolve する promise が返る reader.read().then(function processResult({done, value}) { if (done) return; console.log(value); // read() の呼び出しを再帰する return reader.read().then(processResult); }).catch((error) => { console.error(error); }); 17
  18. node.js pipe readable .pipe(transform) // return readable .pipe(transform) // return

    readable .pipe(writable) // return readable .on('end') .on('error'); 18
  19. whatwg pipe readable .pipeThrough(transform1) // return readable .pipeThrough(transform2) // return

    readable .pipeTo(writable) // return promise .then(done) .catch(fail); 19
  20. whatwg tee() const [r1, r2] = readableStream.tee(); Promise.all([ r1.pipeTo(cache), //

    データは同一参照 r2.pipeTo(upload) ]) .then(() => console.log('done')) .catch((err) => console.error(err)); 20
  21. Push/Pull Source/Sync • Source ◦ underlying source ◦ データの生成元 •

    Sink ◦ underlying sink ◦ データの渡す先 • Push Underlying Source ◦ 勝手に湧き出てくる ◦ TCP, Click, Timer etc • Pull Underlying Source ◦ 欲しい時に取り出す ◦ File, Random etc 21
  22. backpressure • read の生成が write の消費より早い場合 ◦ そのままだと write が間に合わず溢れる

    ◦ write の buffer を見て read を止める方法 • いつ backpressure をかけるか ◦ queuing strategy で決める 22 File Process Network 速 遅 ちょっと待って!
  23. queuing stragtegy • backpressure の戦略 ◦ 内部の queue の管理戦略 ◦

    high-water mark を決める ◦ queue の空き < hwm だったら backpressure • 組み込み queuing strategy ◦ count queuing strategy (HWM == count) ◦ bytelength queuing strategy (HWM == size) 23 速 遅 二つ空くまでは ストップで HWM
  24. 独自 Stream socketStream = new ReadableStream({ start(controller) { socket.on('data', (e)

    => controller.enqueue(e.data)); socket.on('end', () => controller.close()); socket.on('error', (err) => controller.error(err)); }, cancel() { socket.close(); } }); 24
  25. backpressure 付き readable socketStream = new ReadableStream({ start(controller) { socket.on('data',

    (e) => { if (controller.desiredSize <= 0) { socket.readStop(); // backpressure } controller.enqueue(e.data); }); }, pull() { // resume socket.readStart(); }); 25
  26. backpressure 付き writable fileStream = new WritableStream({ start() { return

    fs.open(filename, "w").then(result => { this.fd = result; }); }, write(chunk) { // promise を返す return fs.write(this.fd, chunk, 0, chunk.length); } close() { return fs.close(this.fd); } }); 26
  27. Observable ? 27 • Stream ◦ WHATWG Spec ◦ あくまで

    I/O の抽象化 ◦ 伝達対象はデータの Chunk ◦ backpressure のサポート ◦ tee() を覗き、基本 single-comsumer • Observable ◦ ECMAScript Spec ◦ 連続イベントの抽象化 ◦ イベントそのものだから間引くなどの発想がある ◦ backpressure 無し ◦ multi-consumer 前提 How do readable streams relate to observables or EventTarget?
  28. まとめ 28 • node - whatwg 間で Stream に互換はない ◦

    非同期の表現(promise) から来る差 ◦ stream は promise のジェネレータ ◦ 変換するなら node2whawg の方が楽そう • 似てるけど違う用途 ◦ whatwg stream は I/O のため ◦ observable は event のため • お気持ち ◦ i8c なんてなかった
  29. Fin 29

  30. Jack