Skip to content

Commit

Permalink
Fixed race condition
Browse files Browse the repository at this point in the history
  • Loading branch information
tinchoz49 committed Jul 2, 2020
1 parent fb300c2 commit 816729f
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 32 deletions.
28 changes: 10 additions & 18 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ WriteRequest.prototype.onwrite = function (err, e) {
}

if (!err) {
this.file.updateSize(e.currentTarget.length)
this.file.updateSize(e.currentTarget.length, this.truncating)
}

if (this.truncating) {
Expand All @@ -166,7 +166,6 @@ WriteRequest.prototype.onwrite = function (err, e) {

WriteRequest.prototype.truncate = function () {
this.truncating = true
this.file.truncate()
this.writer.truncate(this.req.offset)
}

Expand Down Expand Up @@ -249,7 +248,10 @@ ReadRequest.prototype.onread = function (err, buf) {
const req = this.req

if (err && this.retry) {
this.retry = false
if (err.code !== 0) {
this.retry = false
}

if (this.lock(this)) {
this.file.clearFile()
this.run(req)
Expand Down Expand Up @@ -286,41 +288,35 @@ class EntryFile {
this._lock = mutexify()
this._file = null
this._size = 0
this._truncated = false
}

get size () {
return this._size
}

updateSize (size) {
if (!this._truncated) {
updateSize (size, truncating) {
if (truncating || size > this._size) {
this._size = size
}

this.clearFile()
}

truncate () {
this._truncated = true
}

clearFile () {
this._file = null
}

get (cb) {
if (this._file && !this._truncated) {
if (this._file) {
return cb(null, this._file)
}

this._lock(release => {
if (this._file && !this._truncated) {
if (this._file) {
return release(cb, null, this._file)
}

this._entry.file(file => {
this._truncated = false
this._file = file
this._size = file.size
release(cb, null, file)
Expand All @@ -329,10 +325,6 @@ class EntryFile {
}

getWritableFile (cb) {
if (!this._truncated) {
return cb(null, this)
}

this.get(cb)
return cb(null, this)
}
}
38 changes: 24 additions & 14 deletions test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const { promisify } = require('util')
const test = require('tape')
const randomAccessTest = require('random-access-test')
const racf = require('./')
Expand All @@ -14,20 +15,8 @@ test('write/read concurrent requests', async t => {
const st = storage('random')

const rand = (min, max) => Math.floor(Math.random() * max) + min

const read = (...args) => new Promise((resolve, reject) => {
st.read(...args, (err) => {
if (err) return reject(err)
resolve()
})
})

const write = (...args) => new Promise((resolve, reject) => {
st.write(...args, (err) => {
if (err) return reject(err)
resolve()
})
})
const read = promisify(st.read.bind(st))
const write = promisify(st.write.bind(st))

try {
await new Promise(resolve => st.open(() => resolve()))
Expand Down Expand Up @@ -55,3 +44,24 @@ test('write/read concurrent requests', async t => {
t.end(err)
}
})

test('write concurrent requests over the same offset different size', async t => {
const st = storage('random')

const write = promisify(st.write.bind(st))

try {
await new Promise(resolve => st.open(() => resolve()))

await Promise.all([
write(0, Buffer.alloc(10)),
write(0, Buffer.alloc(1)),
write(0, Buffer.alloc(5))
])

t.pass('should write multiple requests over the same offset different size')
t.end()
} catch (err) {
t.end(err)
}
})

0 comments on commit 816729f

Please sign in to comment.