Skip to content

Commit

Permalink
fix(gatsby): fix race condition in cache lock (#28097)
Browse files Browse the repository at this point in the history
* chore(gatsby): add try/catch to debug flaky test

* debugging more

* missing arg

* more debug

* set promise sync, not in a .then

* Remove the debugging
  • Loading branch information
pvdz committed Nov 17, 2020
1 parent 061b459 commit 5b2d9b6
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 31 deletions.
8 changes: 3 additions & 5 deletions packages/gatsby/src/cache/cache-fs.ts
Expand Up @@ -228,11 +228,7 @@ DiskStore.prototype.reset = wrapCallback(async function (): Promise<void> {
* @private
*/
DiskStore.prototype._lock = function _lock(filePath): Promise<void> {
return new Promise((resolve, reject) =>
innerLock(resolve, reject, filePath)
).then(() => {
globalGatsbyCacheLock.set(filePath, Date.now())
})
return new Promise((resolve, reject) => innerLock(resolve, reject, filePath))
}

function innerLock(resolve, reject, filePath): void {
Expand All @@ -251,6 +247,8 @@ function innerLock(resolve, reject, filePath): void {
innerLock(resolve, reject, filePath)
}, 50)
} else {
// set sync
globalGatsbyCacheLock.set(filePath, Date.now())
resolve()
}
} catch (e) {
Expand Down
60 changes: 34 additions & 26 deletions packages/gatsby/src/cache/json-file-store.ts
Expand Up @@ -104,32 +104,40 @@ exports.read = async function (path, options): Promise<string> {
}

const externalBuffers = []
const data = JSON.parse(dataString, function bufferReceiver(k, value) {
if (value && value.type === `Buffer` && value.data) {
return Buffer.from(value.data)
} else if (
value &&
value.type === `ExternalBuffer` &&
typeof value.index === `number` &&
typeof value.size === `number`
) {
//JSON.parse is sync so we need to return a buffer sync, we will fill the buffer later
const buffer = Buffer.alloc(value.size)
externalBuffers.push({
index: +value.index,
buffer: buffer,
})
return buffer
} else if (
value &&
value.type === `Infinity` &&
typeof value.sign === `number`
) {
return Infinity * value.sign
} else {
return value
}
})
let data
try {
data = JSON.parse(dataString, function bufferReceiver(k, value) {
if (value && value.type === `Buffer` && value.data) {
return Buffer.from(value.data)
} else if (
value &&
value.type === `ExternalBuffer` &&
typeof value.index === `number` &&
typeof value.size === `number`
) {
//JSON.parse is sync so we need to return a buffer sync, we will fill the buffer later
const buffer = Buffer.alloc(value.size)
externalBuffers.push({
index: +value.index,
buffer: buffer,
})
return buffer
} else if (
value &&
value.type === `Infinity` &&
typeof value.sign === `number`
) {
return Infinity * value.sign
} else {
return value
}
})
} catch (e) {
throw new Error(
"json-file-store failed to JSON.parse this string: `" +
dataString.replace(/\n/g, `⏎`)
)
}

//read external buffers
await Promise.all(
Expand Down

0 comments on commit 5b2d9b6

Please sign in to comment.