2016-01-24 32 views
1

我使用exec-stream與Node.js和管道流通過其他幾個轉換流,最終通過node-brake流來限制數據速率。制動流似乎沒有效果,實際上數據最終在長鏈末端丟失。child_process流反壓

execStream('some-external-binary').pipe(transform1).pipe(transform2).pipe(brake(1024)) 

我認爲正在發生的是,child_processSTDOUT流(內exec-stream)不暫停,因此緩衝填充,直到數據丟失。

child_process流的行爲是這樣嗎?有什麼方法可以讓背壓與child_process流正常工作?

+0

我沒有以exec-stream或節點剎車,但我更想體驗一個完整的例子來探討您的問題。 https://gist.github.com/CodeLenny/007523ae5b13559e644f29b46364c1e4與您遇到的行爲是否相符?它看起來像剎車沒有背壓,但是當使用不同的剎車值時,我沒有得到不同數量的數據。 –

+0

@RyanLeonard有趣。也許這裏一直存在的問題是'node-brake'沒有達到我的預期。是的,這似乎很好地模擬了這個問題。你能否將其作爲回答發佈? – Brad

+0

我已經寫了評論作爲答案。 –

回答

1

我對exec-stream和節點制動不夠熟悉,無法理解數據丟失的所有途徑。

但是,我做了一些小實驗,看看節點制動器是否有背壓效應,您提到的可能是數據丟失的潛在區域。

文件也託管在Gist

### 
Created for http://stackoverflow.com/questions/34982953/child-process-stream-backpressure 
Please pardon the CoffeeScript, but I couldn't stand to extend stream.Transform in native JavaScript. 
### 
fs = require("fs") 
execStream = require("exec-stream") 
brake = require("brake") 

file = fs.createWriteStream("tmp.txt") 

class Double extends require("stream").Transform 
    _transform: (chunk, enc, cb) -> 
    @_last ?= Date.now() 
    @_called ?= [] 
    @_called.push Date.now() - @_last 
    @_last = Date.now() 
    @push chunk.toString() + chunk.toString() 
    cb() 

class UpperCase extends require("stream").Transform 
    _transform: (chunk, enc, cb) -> 
    @push chunk.toString().toUpperCase() 
    cb() 

sum = (nums) -> 
    o = 0 
    o += i for i in nums 
    o 

doTest = (size) -> 

    transform1 = new Double() 
    transform2 = new UpperCase() 
    transform3 = new Double() 

    execStream("dd", ["if=/dev/urandom", "bs=1024", "count=1"]) 
    .pipe(transform1) 
    .pipe(transform2) 
    .pipe(brake(size)) 
    .pipe(transform3) 
    .pipe(file) 

    file.on "finish", -> 
    fs.stat "tmp.txt", (err, stats) -> 
     throw err if err 
     called1 = transform1._called 
     averagePreBrake = sum(called1)/called1.length 
     called2 = transform3._called 
     averagePostBrake = sum(called2)/called2.length 
     console.log """ 
     Generated with brake(#{size}): #{stats.size} 
     Average time between transformations pre-brake: #{averagePreBrake}ms 
     Average time between transformations post-brake: #{averagePostBrake}ms 
     """ 

doTest 1024 
doTest 256 

該過程的結果如下。

stdout from above Coffeescript

我注意到有轉換之間沒有間隙剎車之前。然而,制動器會擾亂線路後面的轉換。鑑於這些數據,我懷疑節點制動器沒有背壓效應。

[截圖由我sh2png工具生成的控制檯輸出]