Skip to content

Commit be89aaf

Browse files
committed
WriteEntry backpressure
1 parent ba73f5e commit be89aaf

File tree

2 files changed

+24
-7
lines changed

2 files changed

+24
-7
lines changed

lib/write-entry.js

+22-6
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ const OPENFILE = Symbol('openfile')
2121
const ONOPENFILE = Symbol('onopenfile')
2222
const CLOSE = Symbol('close')
2323
const MODE = Symbol('mode')
24+
const AWAITDRAIN = Symbol('awaitDrain')
25+
const ONDRAIN = Symbol('ondrain')
2426
const warner = require('./warn-mixin.js')
2527
const winchars = require('./winchars.js')
2628
const stripAbsolutePath = require('./strip-absolute-path.js')
@@ -232,7 +234,7 @@ const WriteEntry = warner(class WriteEntry extends MiniPass {
232234
this.pos = 0
233235
this.remain = this.stat.size
234236
this.length = this.buf.length
235-
this[READ](this.stat.size)
237+
this[READ]()
236238
}
237239

238240
[READ] () {
@@ -284,13 +286,23 @@ const WriteEntry = warner(class WriteEntry extends MiniPass {
284286

285287
const writeBuf = this.offset === 0 && bytesRead === this.buf.length ?
286288
this.buf : this.buf.slice(this.offset, this.offset + bytesRead)
287-
this.remain -= bytesRead
288-
this.blockRemain -= bytesRead
289-
this.pos += bytesRead
290-
this.offset += bytesRead
289+
this.remain -= writeBuf.length
290+
this.blockRemain -= writeBuf.length
291+
this.pos += writeBuf.length
292+
this.offset += writeBuf.length
293+
294+
const flushed = this.write(writeBuf)
295+
if (!flushed)
296+
this[AWAITDRAIN](() => this[ONDRAIN]())
297+
else
298+
this[ONDRAIN]()
299+
}
291300

292-
this.write(writeBuf)
301+
[AWAITDRAIN] (cb) {
302+
this.once('drain', cb)
303+
}
293304

305+
[ONDRAIN] () {
294306
if (!this.remain) {
295307
if (this.blockRemain)
296308
this.write(Buffer.alloc(this.blockRemain))
@@ -339,6 +351,10 @@ class WriteEntrySync extends WriteEntry {
339351
}
340352
}
341353

354+
[AWAITDRAIN] (cb) {
355+
cb()
356+
}
357+
342358
[CLOSE] (cb) {
343359
fs.closeSync(this.fd)
344360
cb()

test/write-entry.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ t.test('zero-byte file, but close fails', t => {
254254
t.match(er, { message: 'poop' })
255255
t.end()
256256
})
257+
ws.resume()
257258
})
258259

259260
t.test('hardlinks', t => {
@@ -597,7 +598,7 @@ t.test('read overflow expectation', t => {
597598
t.throws(_ => new WriteEntry.Sync(f, { cwd: files, maxReadSize: 2 }), expect)
598599
new WriteEntry(f, { cwd: files, maxReadSize: 2 }).on('error', er => {
599600
t.match(er, expect)
600-
})
601+
}).resume()
601602
})
602603

603604
t.test('short reads', t => {

0 commit comments

Comments
 (0)