Upgrade to Pro — share decks privately, control downloads, hide ads and more …

stream between nodejs and whatwg

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for Jxck Jxck
August 08, 2016

stream between nodejs and whatwg

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

Avatar for Jxck

Jxck

August 08, 2016
Tweet

More Decks by Jxck

Other Decks in Technology

Transcript

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

    blog: https://blog.jxck.io • podcast: http://mozaic.fm • Love: music Jack
  2. 11 概念としての Stream File Process Network File Process Network Without

    Stream(データをまとめて次に渡す) With Stream(データを得られた順に次に渡す) then(buffer) pipe(chunk) then(buffer) pipe(chunk)
  3. • 非同期は Callback が基本 • 引数にルールを決めて扱いやすくしよう • 連続するイベントは EventEmitter •

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

    • もちろん Stream は Promise のジェネレータ • (≠ ES6 Generator) • Single-Consumer • カスタマイズはコンストラクタ Stream Promise
  5. 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); });
  6. 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
  7. 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
  8. node.js pipe readable .pipe(transform) // return readable .pipe(transform) // return

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

    readable .pipeTo(writable) // return promise .then(done) .catch(fail); 19
  10. 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
  11. Push/Pull Source/Sync • Source ◦ underlying source ◦ データの生成元 •

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

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

    high-water mark を決める ◦ queue の空き < hwm だったら backpressure • 組み込み queuing strategy ◦ count queuing strategy (HWM == count) ◦ bytelength queuing strategy (HWM == size) 23 速 遅 二つ空くまでは ストップで HWM
  14. 独自 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
  15. 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
  16. 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
  17. 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?
  18. まとめ 28 • node - whatwg 間で Stream に互換はない ◦

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