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 race condition in WithPermissions #5822

Merged
merged 2 commits into from
Jan 28, 2021
Merged

Conversation

fzaninotto
Copy link
Member

@fzaninotto fzaninotto commented Jan 27, 2021

When an app has two components calling <WithPermissions> on the same render phase, a race condition used to lead the second call to never return the actual permissions.

const Test = () => (
  <>
    <WithPermissions component={Foo} />
    <WithPermissions component={Bar} />
  </>
);

Foo was rendered once with empty permissions, then rerendered with the permissions Fetched from the authProvider.
Bar was only rendered once, with empty permissions.

This was a bug due to the permissions from the authProvider being compared to the cache rather than to the initial state.

When an app has two components calling WithPermissions on the same render phase, a race condition used to lead the second call to never return the actual permissions.
@fzaninotto fzaninotto added the RFR Ready For Review label Jan 27, 2021
@fzaninotto fzaninotto added this to the 3.12 milestone Jan 27, 2021
expect(renders).toBe(1); // does not rerender when the getPermissions returns the same permissions
});

it('can be called by two independent components', async () => {
Copy link
Member Author

@fzaninotto fzaninotto Jan 27, 2021

Choose a reason for hiding this comment

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

this test used to fail before the patch

@@ -13,7 +13,7 @@ const emptyParams = {};

// keep a cache of already fetched permissions to initialize state for new
// components and avoid a useless rerender if the permissions haven't changed
const alreadyFetchedPermissions = { '{}': [] };
const alreadyFetchedPermissions = { '{}': undefined };
Copy link
Member Author

Choose a reason for hiding this comment

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

This was another regression introduced in 3.11. Before, WithPermissions injected undefined on mount. After, it injected an empty array.

@@ -71,7 +71,7 @@ const usePermissionsOptimized = (params = emptyParams) => {
error,
});
});
}, [getPermissions, params, setState]);
}, [getPermissions, key]); // eslint-disable-line react-hooks/exhaustive-deps
Copy link
Member Author

Choose a reason for hiding this comment

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

this is done on purpose, and there is no way around it

(worked on my machine!)
@djhi djhi merged commit 774bdb2 into master Jan 28, 2021
@djhi djhi deleted the fix-WithPermissions-race-condition branch January 28, 2021 08:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
RFR Ready For Review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants