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

Use a WeakMap to store parent of subobjects in nodes #2812

Merged
merged 1 commit into from
Nov 7, 2017

Conversation

pieh
Copy link
Contributor

@pieh pieh commented Nov 6, 2017

this prevents mutating plugin data that is deeper in object properites
fixes #2772

For context check #2772 and my comment there

@gatsbybot
Copy link
Collaborator

gatsbybot commented Nov 6, 2017

Deploy preview ready!

Built with commit 11c2dd3

https://deploy-preview-2812--gatsbygram.netlify.com

@gatsbybot
Copy link
Collaborator

gatsbybot commented Nov 6, 2017

Deploy preview ready!

Built with commit 11c2dd3

https://deploy-preview-2812--using-drupal.netlify.com

@jquense
Copy link
Contributor

jquense commented Nov 6, 2017

thanks for the PR! I think the better option to fix this is probably to have createNode not mutate the input in the first place...or whereever the mutation is happening. We don't necessarily want to work around that behavior when it probably isn't intentional in the first place

@pieh
Copy link
Contributor Author

pieh commented Nov 6, 2017

Updated PR with suggested change.

Previous version of "fix" just in case for reference - pieh@f4e52bd

// Make deep copy of node before mutating it, this makes sure original object
// will not fail validation due to unexpected fields.
// (reference: https://github.com/gatsbyjs/gatsby/issues/2772 )
node = _.cloneDeep(node)
Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry! this isn't what I meant. I'd like to avoid a deep clone entirely because it can very expensive, and we have no idea what content or structure nodes will have. Instead I'd like to find the places where mutation is happening and remove them, rather then make mutation safe.

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, right, I had brain lag or something - now i read your comment again and think to myself how did I understand it the way I did before ...

So if gatsby shouldn't mutate then you would have revert this - 656299d

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmmmm yeah we could move that code into a library that then is used in source/transformer plugins that need it.

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah this is a bit tough, since we sort of need to hope consumers play nice and don't mutate...the problem tho is that enforcing generally it is pretty costly especially here where nodes may be/are complex data structures.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Could you elaborate a little what problem 656299d fixed? Is it needed in all nodes or is just for source/transformers plugins? Maybe I could just change createNode and add argument to opt-out of adding _PARENT fields and just opt-out of it for plugin data? This would avoid any cloning at all (obviously prefered solution).

Copy link
Contributor

Choose a reason for hiding this comment

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

See this comment #2567 (comment) It's basically a workaround for GraphQL as it doesn't let you know what the parent of a sub-object is which breaks Gatsby in subtle ways.

Avoiding mutating plugins would be a great start. So yeah, question is should we opt-in to adding _PARENT or opt-out.

I think it's a generally useful/needed pattern which is why I added it to actions.js so I'm leaning towards opt-out. Thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

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

maybe instead of tagging each sub object we could use a WeakMap hashing objects to parent id? e.g. something like:

map = new WeakMap()

eachChildObject(node, obj => { 
  map.set(obj, node.id)
})

then expose a getParent api perhaps?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ooo that's good! Yeah, that sounds much nicer. @pieh you have time to work on this by chance? I'm pretty strapped for time over next few days / week.

@pieh
Copy link
Contributor Author

pieh commented Nov 7, 2017

updated PR

tested against repository linked in #2567 (comment) to check if "parent fix" still works

@KyleAMathews KyleAMathews changed the title make deep copy of plugin data before creating graphql node from it Use a WeakMap to store parent of subobjects in nodes Nov 7, 2017
@KyleAMathews
Copy link
Contributor

🙇 this is awesome!

@KyleAMathews KyleAMathews merged commit 8ac749f into gatsbyjs:master Nov 7, 2017
@jlengstorf
Copy link
Contributor

Hiya @pieh! 👋

This is definitely late, but on behalf of the entire Gatsby community, I wanted to say thank you for being here.

Gatsby is built by awesome people like you. Let us say “thanks” in two ways:

  1. We’d like to send you some Gatsby swag. As a token of our appreciation, you can go to the Gatsby Swag Store and log in with your GitHub account to get a coupon code good for one free piece of swag. (We’ve got t-shirts and hats, plus some socks that are really razzing our berries right now.)
  2. If you’re not already part of it, we just invited you to join the Gatsby organization on GitHub. This will add you to our team of maintainers. You’ll receive an email shortly asking you to confirm. By joining the team, you’ll be able to label issues, review pull requests, and merge approved pull requests.

If you have questions, please don’t hesitate to reach out to us: tweet at @gatsbyjs and we’ll come a-runnin’.

Thanks again! 💪💜

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.

CSS additionalProperties issue
5 participants