Skip to content

Commit

Permalink
fix(gatsby): fix stale query results on data updates (#28986) (#28994)
Browse files Browse the repository at this point in the history
* Add failing test

* fix(gatsby): fix stale query results on data updates

* narrow the scope of the change

* Address review comments

* remove accidentally added stuff

(cherry picked from commit 811c2a8)

Co-authored-by: Vladimir Razuvaev <vladimir.razuvaev@gmail.com>
  • Loading branch information
GatsbyJS Bot and vladar committed Jan 13, 2021
1 parent f632c0a commit c172848
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
64 changes: 64 additions & 0 deletions packages/gatsby/src/query/__tests__/data-tracking.js
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,70 @@ describe(`query caching between builds`, () => {
}, 999999)
})

describe(`Changed node previously not used to be used by the query`, () => {
let nodeChangeCounter = 1
beforeEach(() => {
setAPIhooks({
sourceNodes: (nodeApiContext, _pluginOptions) => {
const { createTestNode } = getTypedNodeCreators(nodeApiContext)

for (let i = 1; i <= nodeChangeCounter; i++) {
createTestNode({
id: `test-${i}`,
slug: `foo${i}`,
content: `Lorem ipsum.`,
})
}

nodeChangeCounter++
},
})
setPageQueries({})
setStaticQueries({
"static-query-1": `
{
test(slug: { eq: "foo2" }) {
slug
content
}
}
`,
"static-query-2": `
{
test(slug: { eq: "foo3" }) {
slug
content
}
}
`,
})
})

it(`rerunning after cache clearing - should run all queries`, async () => {
const { staticQueriesThatRan } = await setup({
restart: true,
clearCache: true,
})

// all queries to run
expect(staticQueriesThatRan).toEqual([`static-query-1`, `static-query-2`])
}, 99999)

it(`changing node to be used by any query triggers running that query (no restart)`, async () => {
const { staticQueriesThatRan } = await setup()

// runs the query with filter `slug: { eq: "foo1" }`
expect(staticQueriesThatRan).toEqual([`static-query-1`, `static-query-2`])
}, 999999)

it(`changing node to be used by any query triggers running that query (with restart)`, async () => {
const { staticQueriesThatRan } = await setup({ restart: true })

// runs the query with filter `slug: { eq: "foo2" }`
expect(staticQueriesThatRan).toEqual([`static-query-2`])
}, 999999)
})

describe(`Changing data used in multiple queries properly invalidates them`, () => {
let nodeChangeCounter = 1
beforeAll(() => {
Expand Down
13 changes: 13 additions & 0 deletions packages/gatsby/src/schema/node-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,19 @@ class LocalNodeModel {
this.trackInlineObjectsInRootNode(result)
} else {
result = null

// Couldn't find matching node.
// This leads to a state where data tracking for this query gets empty.
// It means we will NEVER re-run this query on any data updates
// (even if a new node matching this query is added at some point).
// To workaround this, we have to add a connection tracking to re-run
// the query whenever any node of this type changes.
if (pageDependencies.path) {
this.createPageDependency({
path: pageDependencies.path,
connection: gqlType.name,
})
}
}
} else if (result) {
result.forEach(node => this.trackInlineObjectsInRootNode(node))
Expand Down

0 comments on commit c172848

Please sign in to comment.