Skip to content

Commit

Permalink
write data to old file while reopen failed
Browse files Browse the repository at this point in the history
  • Loading branch information
xiedacon committed Mar 13, 2021
1 parent 04635c0 commit dd63119
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 10 deletions.
39 changes: 30 additions & 9 deletions index.js
Expand Up @@ -20,23 +20,35 @@ function openFile (file, sonic) {
sonic._opening = true
sonic._writing = true
sonic._asyncDrainScheduled = false
sonic.file = file

// NOTE: 'error' and 'ready' events emitted below only relevant when sonic.sync===false
// for sync mode, there is no way to add a listener that will receive these

function fileOpened (err, fd) {
if (err) {
sonic.emit('error', err)
sonic._reopening = false
sonic._writing = false
sonic._opening = false

if (sonic.sync) {
process.nextTick(() => sonic.emit('error', err))
} else {
sonic.emit('error', err)
}
return
}

sonic.fd = fd
sonic.file = file
sonic._reopening = false
sonic._opening = false
sonic._writing = false

sonic.emit('ready')
if (sonic.sync) {
process.nextTick(() => sonic.emit('ready'))
} else {
sonic.emit('ready')
}

if (sonic._reopening) {
return
Expand All @@ -50,9 +62,13 @@ function openFile (file, sonic) {
}

if (sonic.sync) {
const fd = fs.openSync(file, 'a')
fileOpened(null, fd)
process.nextTick(() => sonic.emit('ready'))
try {
const fd = fs.openSync(file, 'a')
fileOpened(null, fd)
} catch (err) {
fileOpened(err)
throw err
}
} else {
fs.open(file, 'a', fileOpened)
}
Expand Down Expand Up @@ -238,9 +254,14 @@ SonicBoom.prototype.reopen = function (file) {
return
}

fs.close(this.fd, (err) => {
if (err) {
return this.emit('error', err)
const fd = this.fd
this.once('ready', () => {
if (fd !== this.fd) {
fs.close(fd, (err) => {
if (err) {
return this.emit('error', err)
}
})
}
})

Expand Down
67 changes: 66 additions & 1 deletion test.js
Expand Up @@ -21,7 +21,9 @@ function file () {
tearDown(() => {
files.forEach((file) => {
try {
fs.unlinkSync(file)
if (fs.existsSync(file)) {
fs.unlinkSync(file)
}
} catch (e) {
console.log(e)
}
Expand Down Expand Up @@ -538,6 +540,69 @@ function buildTests (test, sync) {
})
}, 0)
})

test('reopen throws an error', (t) => {
t.plan(sync ? 10 : 9)

const fakeFs = Object.create(fs)
const SonicBoom = proxyquire('.', {
fs: fakeFs
})

const dest = file()
const stream = new SonicBoom({ dest, sync })

t.ok(stream.write('hello world\n'))
t.ok(stream.write('something else\n'))

const after = dest + '-moved'

stream.on('error', () => {
t.pass('error emitted')
})

stream.once('drain', () => {
t.pass('drain emitted')

fs.renameSync(dest, after)
if (sync) {
fakeFs.openSync = function (file, flags) {
t.pass('fake fs.openSync called')
throw new Error('open error')
}
} else {
fakeFs.open = function (file, flags, cb) {
t.pass('fake fs.open called')
setTimeout(() => cb(new Error('open error')), 0)
}
}

if (sync) {
try {
stream.reopen()
} catch (err) {
t.pass('reopen throwed')
}
} else {
stream.reopen()
}

setTimeout(() => {
t.ok(stream.write('after reopen\n'))

stream.end()
stream.on('finish', () => {
fs.readFile(after, 'utf8', (err, data) => {
t.error(err)
t.equal(data, 'hello world\nsomething else\nafter reopen\n')
})
})
stream.on('close', () => {
t.pass('close emitted')
})
}, 0)
})
})
}

test('retry on EAGAIN', (t) => {
Expand Down

0 comments on commit dd63119

Please sign in to comment.