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

stream between nodejs and whatwg

Jxck
August 08, 2016

stream between nodejs and whatwg

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

Jxck

August 08, 2016
Tweet

More Decks by Jxck

Other Decks in Technology

Transcript

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

    View Slide

  2. ● id: Jxck
    ● github: Jxck
    ● twitter: @jxck_
    ● blog: https://blog.jxck.io
    ● podcast: http://mozaic.fm
    ● Love: music
    Jack

    View Slide

  3. mozaic.fm ep10 Node.js
    3
    https://mozaic.fm/episodes/10/nodejs.html

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  9. Stream とは?(哲学)
    9

    View Slide

  10. Common
    Terminology
    10

    View Slide

  11. 11
    概念としての Stream
    File Process Network
    File Process Network
    Without Stream(データをまとめて次に渡す)
    With Stream(データを得られた順に次に渡す)
    then(buffer)
    pipe(chunk)
    then(buffer)
    pipe(chunk)

    View Slide

  12. 12
    両者の供述を聞く

    View Slide

  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

    View Slide

  14. 14
    In WHATWG
    ● 非同期は Promise を返してこう
    ● Async/Await でそれを便利にしよう
    ● もちろん Stream は Promise のジェネレータ
    ● (≠ ES6 Generator)
    ● Single-Consumer
    ● カスタマイズはコンストラクタ
    Stream Promise

    View Slide

  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);
    });

    View Slide

  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

    View Slide

  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

    View Slide

  18. node.js pipe
    readable
    .pipe(transform) // return readable
    .pipe(transform) // return readable
    .pipe(writable) // return readable
    .on('end')
    .on('error');
    18

    View Slide

  19. whatwg pipe
    readable
    .pipeThrough(transform1) // return readable
    .pipeThrough(transform2) // return readable
    .pipeTo(writable) // return promise
    .then(done)
    .catch(fail);
    19

    View Slide

  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

    View Slide

  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

    View Slide

  22. backpressure
    ● read の生成が write の消費より早い場合
    ○ そのままだと write が間に合わず溢れる
    ○ write の buffer を見て read を止める方法
    ● いつ backpressure をかけるか
    ○ queuing strategy で決める
    22
    File Process Network
    速 遅
    ちょっと待って!

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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?

    View Slide

  28. まとめ
    28
    ● node - whatwg 間で Stream に互換はない
    ○ 非同期の表現(promise) から来る差
    ○ stream は promise のジェネレータ
    ○ 変換するなら node2whawg の方が楽そう
    ● 似てるけど違う用途
    ○ whatwg stream は I/O のため
    ○ observable は event のため
    ● お気持ち
    ○ i8c なんてなかった

    View Slide

  29. Fin
    29

    View Slide

  30. Jack

    View Slide