Skip to content

Commit

Permalink
fix: more work to prevent queries from running when there's in-progre…
Browse files Browse the repository at this point in the history
…ss node processing (#8859)

* More work to prevent queries from running when there's in-progress node processing

* Remove unused code

* Turns out having query running pause on CREATE_NODE is all that's needed

* Make state machine local to each instance of the plugin
  • Loading branch information
KyleAMathews authored and pieh committed Oct 9, 2018
1 parent 2605aa0 commit 00eeef0
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 50 deletions.
51 changes: 1 addition & 50 deletions packages/gatsby-source-filesystem/src/gatsby-node.js
Expand Up @@ -44,27 +44,6 @@ const createFSMachine = () =>
},
},
},
PROCESSING: {
initial: `BOOTSTRAPPING`,
states: {
BOOTSTRAPPING: {
on: {
BOOTSTRAP_FINISHED: `IDLE`,
},
},
IDLE: {
on: {
EMIT_FS_EVENT: `PROCESSING`,
},
},
PROCESSING: {
on: {
QUERY_QUEUE_DRAINED: `IDLE`,
TOUCH_NODE: `IDLE`,
},
},
},
},
},
})

Expand Down Expand Up @@ -95,7 +74,6 @@ See docs here - https://www.gatsbyjs.org/packages/gatsby-source-filesystem/

const fsMachine = createFSMachine()
let currentState = fsMachine.initialState
let fileNodeQueue = new Map()

// Once bootstrap is finished, we only let one File node update go through
// the system at a time.
Expand All @@ -105,26 +83,6 @@ See docs here - https://www.gatsbyjs.org/packages/gatsby-source-filesystem/
`BOOTSTRAP_FINISHED`
)
})
emitter.on(`TOUCH_NODE`, () => {
// If we create a node which is the same as the previous version, createNode
// returns TOUCH_NODE and then nothing else happens so we listen to that
// to return the state back to IDLE.
currentState = fsMachine.transition(currentState.value, `TOUCH_NODE`)
})

emitter.on(`QUERY_QUEUE_DRAINED`, () => {
currentState = fsMachine.transition(
currentState.value,
`QUERY_QUEUE_DRAINED`
)
// If we have any updates queued, run one of them now.
if (fileNodeQueue.size > 0) {
const toProcess = fileNodeQueue.get(Array.from(fileNodeQueue.keys())[0])
fileNodeQueue.delete(toProcess.id)
currentState = fsMachine.transition(currentState.value, `EMIT_FS_EVENT`)
createNode(toProcess)
}
})

const watcher = chokidar.watch(pluginOptions.path, {
ignored: [
Expand All @@ -147,13 +105,7 @@ See docs here - https://www.gatsbyjs.org/packages/gatsby-source-filesystem/
createNodeId,
pluginOptions
).then(fileNode => {
if (currentState.value.PROCESSING === `PROCESSING`) {
fileNodeQueue.set(fileNode.id, fileNode)
} else {
currentState = fsMachine.transition(currentState.value, `EMIT_FS_EVENT`)
createNode(fileNode)
}

createNode(fileNode)
return null
})
return fileNodePromise
Expand Down Expand Up @@ -201,7 +153,6 @@ See docs here - https://www.gatsbyjs.org/packages/gatsby-source-filesystem/
// It's possible the file node was never created as sometimes tools will
// write and then immediately delete temporary files to the file system.
if (node) {
currentState = fsMachine.transition(currentState.value, `EMIT_FS_EVENT`)
deleteNode({ node })
}
})
Expand Down
14 changes: 14 additions & 0 deletions packages/gatsby/src/internal-plugins/query-runner/query-queue.js
Expand Up @@ -61,8 +61,22 @@ const queue = new Queue((plObj, callback) => {
)
}, queueOptions)

// Pause running queries when new nodes are added (processing starts).
emitter.on(`CREATE_NODE`, () => {
queue.pause()
})

// Resume running queries as soon as the api queue is empty.
emitter.on(`API_RUNNING_QUEUE_EMPTY`, () => {
queue.resume()
})

queue.on(`drain`, () => {
emitter.emit(`QUERY_QUEUE_DRAINED`)
})

queue.on(`task_queued`, () => {
emitter.emit(`QUERY_ENQUEUED`)
})

module.exports = queue

0 comments on commit 00eeef0

Please sign in to comment.