Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: check for dirty pages when nodes are deleted (so queries are ru-run and data is removed from pages) #11831

Merged
merged 11 commits into from Feb 20, 2019

Conversation

KyleAMathews
Copy link
Contributor

@KyleAMathews KyleAMathews requested a review from a team as a code owner February 17, 2019 06:50
@KyleAMathews
Copy link
Contributor Author

Ha wait. @pieh reverted this exact code last August #7388 🤔

@KyleAMathews
Copy link
Contributor Author

API_RUNNER_QUEUE_EMPTY is definitely not being called when deleting the markdown file.

@KyleAMathews
Copy link
Contributor Author

The problem with #7388 was it assumed that all DELETE_NODEs would lead to API calls — which in simple node deletions it doesn't.

How to detect though when just a delete happens and nothing else.

@KyleAMathews
Copy link
Contributor Author

So funny solution but perhaps a good idea is we could add a onDeleteNode API hook — which would mean API_RUNNING_QUEUE_EMPTY would now always be called 😎

@KyleAMathews
Copy link
Contributor Author

I think I work around #7300 by checking that the DELETE_NODE node type is File as files are only deleted by gatsby-source-filesystem when a file is actually deleted. This wouldn't lead to any sort of infinite loop as if the file was immediately recreated, then runCreatePages wouldn't get called again until the new nodes are finished being created.

The problem with this is that then we'd need to add support for each new source plugin that deletes nodes. So onDeleteNode seems like a strong solution.

@pieh
Copy link
Contributor

pieh commented Feb 17, 2019

This is problem with any stateful source plugin - in our monorepo only filesystem behaves like that - but sanity plugin (with live data refresh feature enabled) that doesn't rely on sourceNodes API hook for deleting nodes has exactly same problem.

This only happens for node deletion, because node updates trigger onCreateNode API to run which then will emit API_RUNNER_QUEUE_EMPTY (this doesn't happen for node deletion).

We were discussing and pairing on this with @sidharthachatterjee earlier and my idea was to "fake" API running after DELETE_NODE so we could use existing API_RUNNER_QUEUE_EMPTY event handling. This would make sure we don't trigger creating pages / query running if deleteNode was called during API run (i.e. in onCreatePage that was causing issues that I "fixed" but caused regressions elsewhere).

@KyleAMathews
Copy link
Contributor Author

What did you think of the onDeleteNode idea?

@pieh
Copy link
Contributor

pieh commented Feb 17, 2019

I didn't want to add new public API that there is probably no practical use for. But both adding onDeleteNode and faking API run would achieve same result - only question is do we want this new public API?

@KyleAMathews
Copy link
Contributor Author

👍 yeah, it seems potentially useful but until we have concrete use cases for onDeleteNode, there's no point in adding. A special fake invocation of api-runner sounds like a great solution and can be swapped out easily for a real call if we ever add onDeleteNode.

@pieh
Copy link
Contributor

pieh commented Feb 17, 2019

I think this will also fix #10844 (which to me seems like same issue) - will validate now

@pieh
Copy link
Contributor

pieh commented Feb 17, 2019

After tests with https://github.com/rexxars/gatsby-node-update-bugs it fixes the node deletion not causing rerunning createPages / rerunning queries

But I uncovered bug with page-hot-reloader not cleaning up not re-created pages -

timestamp check is not working because it compares number to date string - solution is to use Date.now() in
const timestamp = new Date().toJSON()

I'm checking out Bug #2 from the repro repo description right now - might we can kill all of those with one stone

@KyleAMathews
Copy link
Contributor Author

Great catch on updatedAt! And yikes 😱 types would be nice in core. No idea why I used Date.now() for page.createdAt. Doing a quick look around, it looks like 85% of dates are ISO8601 and the remaining 15% are randomly unix timestamps.

@KyleAMathews
Copy link
Contributor Author

Oh and verified that pages are added/removed on the dev 404 page — which wasn't updating smoothly for some reason.

@KyleAMathews
Copy link
Contributor Author

Looking at @rexxars' (awesome!) repro — it looks like this fixes part of things — still seeing a problem where the title updates which causes the slug to change — for some reason the query for the new/changed page isn't run until I save the page component. I recall seeing an issue around changes to pageContext not triggering re-runs of GraphQL. Investigating...

@KyleAMathews
Copy link
Contributor Author

#7375 (comment)

@KyleAMathews
Copy link
Contributor Author

Let's get this in with these fixes. Working on more fixes for https://github.com/rexxars/gatsby-node-update-bugs in #11897

@@ -45,7 +46,7 @@ const runCreatePages = async () => {
})
.map(p => p.id)

const timestamp = new Date().toJSON()
const timestamp = Date.now()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new Date().toJSON() => "2019-02-20T10:47:41.468Z"
Date.now() => 1550659670910

I don't know how page.updatedAt looks so no idea if this is good or bad 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah... for some reason I made a few types (like page) use unix timestamps instead of iso8601 :-(

So this check was failing before.

@@ -157,7 +157,7 @@ module.exports = async (api, args = {}, pluginSource) =>
})

// Check that the API is documented.
if (!apiList[api]) {
if (!apiList[api] && api !== `FAKE_API_CALL`) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't see FAKE_API_CALL if you could point me in the right direction that would be awesome

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh lemme add a comment on this. It's a bit weird :-D

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@wardpeet wardpeet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works like a charm tested it with blog-starter! 🎉

we also fix the following issue when recreating a page

warning Action createPage was called outside of its expected asynchronous lifecycle createPages in default-site-plugin.
Ensure that you return a Promise from createPages and are awaiting any asynchronous method invocations (like graphql or http requests).
For more info and debugging tips: see https://gatsby.app/sync-actions

File /home/ward/projects/tmp/my-blog-starter/gatsby-node.js:40:7
  38 |       const next = index === 0 ? null : posts[index - 1].node
  39 |
> 40 |       createPage({
     |       ^
  41 |         path: post.node.fields.slug,
  42 |         component: blogPost,
  43 |         context: {

@KyleAMathews
Copy link
Contributor Author

Thanks for the review!

@KyleAMathews KyleAMathews merged commit 1fff689 into master Feb 20, 2019
@KyleAMathews KyleAMathews deleted the fix-delete-hot-reload branch February 20, 2019 11:16
@KyleAMathews
Copy link
Contributor Author

Do you mean we need to fix that warning? Like the new warning is popping up while developing a site?

@KyleAMathews
Copy link
Contributor Author

And you create a new page?

@wardpeet
Copy link
Contributor

no it's fixed :) Else I wouldn't approve 😄

When removing a blog post and when I try to rollback the blogpost I got an error. Your fix also fixes this.

wardpeet pushed a commit that referenced this pull request Mar 20, 2019
…r edits (#12671)

If in `gatsby-node.js` we add
```js
exports.onCreatePage = ({ actions, page }) => {
  actions.createPage(page)
}
```

Next time any node update, pages created by `gatsby-plugin-page-creator` will be deleted. This is regression introduced by fix in #11831 (that fixed the problem of pages never getting deleted)

The problem is that when we do `createPage` by plugin/site that isn't implementing `createPagesStatefully` it will be marked to be deleted.

This change keeps track if original API was `createPages` or `createPagesStatefully` by using `traceId` instead of directly checking what plugin created the page in the end.

Fixes #12143
pragmaticpat pushed a commit to pragmaticpat/gatsby that referenced this pull request Apr 28, 2022
…run and data is removed from pages) (gatsbyjs#11831)

* fix: check for dirty pages when nodes are deleted (so queries are ru-run and data is removed from pages)

* typo fix

* Use fake API call as suggested by @pieh

* better name

* Fix comparision as page.updatedAt is a unix timestamp

* Remove page when deleted from internal query running cache so it can be run again if page recreated

* WIP

* MORE WIP

* Revert "MORE WIP"

This reverts commit 890fb36.

* Revert "WIP"

This reverts commit 190625f.

* Document FAKE_API_CALL
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants