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

ContextProviderExtension: use spread operator instead of clonedeep #6243

Merged
merged 1 commit into from Aug 6, 2020

Conversation

sahil143
Copy link
Contributor

@sahil143 sahil143 commented Aug 6, 2020

Fixes: https://issues.redhat.com/browse/ODC-4430

Analysis: The guided tour was not working because of some issue with ContextProvider extension.

Solution: using spread operator instead of lodash cloneDeep while sanitizing extension seems to fix it.

Browser:

  • Chrome

@sahil143
Copy link
Contributor Author

sahil143 commented Aug 6, 2020

/cc @rohitkrai03 @vojtechszocs

@sahil143
Copy link
Contributor Author

sahil143 commented Aug 6, 2020

/kind bug

@openshift-ci-robot openshift-ci-robot added the kind/bug Categorizes issue or PR as related to a bug. label Aug 6, 2020
@glekner
Copy link
Contributor

glekner commented Aug 6, 2020

I believe you should create a BZ for this

@andrewballantyne
Copy link
Contributor

I believe you should create a BZ for this

Until the repo is setup to block without bugzillas, there is no requirement to do that unless you're backporting.

@@ -45,7 +45,7 @@ export class PluginStore {
this.extensions = _.flatMap(
plugins.map((p) =>
p.extensions.map((e, index) =>
Object.freeze(augmentExtension(sanitizeExtension(_.cloneDeep(e)), p.name, index)),
Object.freeze(augmentExtension(sanitizeExtension({ ...e }), p.name, index)),
Copy link
Contributor

Choose a reason for hiding this comment

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

The premise of this change makes me uncomfortable. Something is "hoping" for the mutation in order to work. That's a bigger issue we should look to fix at some point (doesn't need to block this fix).

cc @vojtechszocs

Copy link
Contributor

Choose a reason for hiding this comment

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

@andrewballantyne @glekner @sahil143

ContextProvider extensions directly reference React Context.Provider component via their Provider property.

According to docs, _.cloneDeep clones arrays, array buffers, booleans, date objects, maps, numbers, Object objects, regexes, sets, strings, symbols, and typed arrays.

Debugging shows that Context.Provider component references the Context object. Since _.cloneDeep works recursively, this seems to break the link between Context.Provider and the original Context object, which explains why it's not updated at runtime.

TL;DR we can use _.clone instead of _.cloneDeep or keep using object spread { ...e }.

Copy link
Contributor

Choose a reason for hiding this comment

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

Interesting 🤔 -- both shallow spreads/clones and deep clones change the object reference ... but something nested within the data is being referenced instead. Object mutations are tricky beasts, as long as we don't get into a practice of doing it, we can take some assumptions here.

I find it odd that we freeze the object (MDN docs), which I'm finding out doesn't actually prevent mutations of nested values 🤔 , so it's mutable after the fact too?

const obj = {
  prop: {
    value: {
      item: 42
    }
  }
};

Object.freeze(obj);

try {
obj.prop.value.item = 33;
// Throws an error in strict mode
} catch(e) {}

console.log(obj.prop.value.item);
// output: 33

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah doh! I guess I assumed it would be recursive, but it makes sense that it is not. It's freezing the top level object and it's direct prosperities but each property that is an object is a new object that needs to be frozen.

EDIT: which is explained here if I read the whole MDN page lol

Copy link
Contributor

Choose a reason for hiding this comment

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

@andrewballantyne

Object mutations are tricky beasts, as long as we don't get into a practice of doing it, we can take some assumptions here.

Right, we currently assume that static plugins won't modify extension objects in any way within their plugin.tsx module.

I find it odd that we freeze the object (MDN docs), which I'm finding out doesn't actually prevent mutations of nested values , so it's mutable after the fact too?

Yes, Object.freeze affects only the properties declared directly on that object. So we're basically enforcing that extension's type, properties and flags (plus computed ones pluginName and uid) cannot be changed.

Maybe we should do a deep freeze instead of just the regular one. That way, even if a plugin tries to modify some nested property like e.properties.foo it would stay the same. We can do this as part of #6101.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, wonder if we should just fix the mutations within this file @vojtechszocs for a little QoL... we don't need to do it part of this PR though.

https://github.com/openshift/console/pull/6243/files/219277593bbf377d8427971251d8101a43eb0af9#diff-7aa93e478ecd93277b784e0c7ea91f8cR5-R20

Replace with spreads against the original object... it's still a mutation, but it's a smaller scoped one? Again, not sure if this is anything more than academic heh.

@invincibleJai
Copy link
Member

I can see guided tour in developer perspective with this fix.

@vojtechszocs
Copy link
Contributor

/lgtm

@openshift-ci-robot openshift-ci-robot added lgtm Indicates that a PR is ready to be merged. approved Indicates a PR has been approved by an approver from all required OWNERS files. labels Aug 6, 2020
@openshift-bot
Copy link
Contributor

/retest

Please review the full test history for this PR and help us cut down flakes.

@andrewballantyne
Copy link
Contributor

/retest

@openshift-bot
Copy link
Contributor

/retest

Please review the full test history for this PR and help us cut down flakes.

@openshift-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: sahil143, vojtechszocs

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-merge-robot openshift-merge-robot merged commit 5e8c376 into openshift:master Aug 6, 2020
@spadgett spadgett added this to the v4.6 milestone Aug 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. component/sdk Related to console-plugin-sdk kind/bug Categorizes issue or PR as related to a bug. lgtm Indicates that a PR is ready to be merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants