Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Exert backpressure when pipeline is not flowing
If the pipeline as a whole is not flowing, then it should return `false` from any write operation. Since the Pipeline listens to the tail stream's `data` event, the streams in the pipeline always are in flowing mode. However, the Pipeline itself may not be, so it would return `true` from writes inappropriately, allowing data to be buffered up in the Pipeline excessively. This would not cause any significant issues in most cases, except excess memory usage. Discovered while debugging npm/npm-registry-fetch#23
- Loading branch information
Showing
2 changed files
with
38 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
const Pipeline = require('../') | ||
const Minipass = require('minipass') | ||
const t = require('tap') | ||
|
||
t.test('verify that pipelines exert backpressure properly', t => { | ||
const tail = new class extends Minipass { | ||
write (chunk, encoding, cb) { | ||
const ret = super.write(chunk, encoding, cb) | ||
t.equal(ret, true, 'tail write should return true') | ||
return ret | ||
} | ||
} | ||
|
||
const head = new class extends Minipass { | ||
write (chunk, encoding, cb) { | ||
const ret = super.write(chunk, encoding, cb) | ||
t.equal(ret, true, 'head write should return true') | ||
return ret | ||
} | ||
} | ||
|
||
const pipe = new Pipeline({ encoding: 'utf8' }, head, tail) | ||
|
||
for (let i = 0; i < 5; i++) { | ||
t.equal(pipe.write('' + i), false, 'write is false until flowing') | ||
} | ||
|
||
const p = pipe.concat().then(d => t.equal(d, '0123456789', 'got expected data')) | ||
|
||
for (let i = 5; i < 10; i++) { | ||
t.equal(pipe.write('' + i), true, 'write is true when pipeline is flowing') | ||
} | ||
|
||
pipe.end() | ||
|
||
return p | ||
}) |