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
Allow developers to short circuit potentially expensive is_private ch… #972
Allow developers to short circuit potentially expensive is_private ch… #972
Conversation
…eck in model layer
@CodeProKid this is breaking tests 🤔 |
WP core seems to use Fox example here's how Pre skip: Actual value filtering: Maybe we should follow the same convention? Now this PR removes the possibility to reference the original private value. |
## Bugfixes - MenuItems are stored in the post table and should use the post loader. To use the post loader properly, the menu item IDs should be encoded as `post:$id` but were encoded as `nav_menu_item:$id` which breaks the principles of the Relay spec. This fixes that. MenuItems now output ids encoded as `post:$id`
Release/v1.1.2
There has been a long-standing performance issue with the is_private method of the User model, because it attempts to count the number of published posts for each user, a potentially very expensive operation. And since the operation is uncached, this can very quickly overwhelm the database. More discussion of the issue: wp-graphql#961 At Quartz, this has prevented us from upgrading WPGraphQL, and it appears to have affected other users as well. A few different PRs exist to address this issue: wp-graphql#962 wp-graphql#972 wp-graphql#1677 This PR is my attempt to fix this issue the way that Jason and others have described as ideal: using DataLoader. Instead of creating a new loader (e.g., "UserVisibilityLoader"), I am including this in UserLoader. The reason is that they seem tightly coupled and making them separate would just introduce unnecessary complexity. You'd need to remember to use UserVisibilityLoader everywhere you used UserLoader or risk losing the performance benefit it provides. My fix simply plugs into the existing "loadKeys" implementation and produces a single query that determines visibility for each user. I'd love feedback on the efficiency of this query; I hope that this is good enough to sidestep the need for caching. If its not possible to generate a single efficient query, generating an extra query for each user along the lines of `SELECT id FROM wp_posts WHERE post_author = X LIMIT 1` seems like the next best approach. Finally, we need a way to provide the visibility to the User model. Luckily, WP_User is not a final class and provides a setter: https://developer.wordpress.org/reference/classes/wp_user/__set/ This allows us to set an "is_private" property on the WP_User instance, which is then available to the model via "$this->data". This seems to be done widely, but we could implement a wrapper around WP_User if we wanted to avoid mutating WP_User instances. From there, it's a very simple matter of having the User model check this property.
# Conflicts: # src/Model/Model.php
|
…ore consistent with existing filter.
@zacscott I got this PR updated and passing tests. This should help with the issue you were facing. @imranhsayed @chriszarate @benmay this should help with what ya'll were facing as well? I still plan to fix the SQL check as well that checks for published authors (there are a few open PRs for that, but this should unblock you until I review those PRs and make some final decisions on that). |
Thank you @jasonbahl |
Thank you @jasonbahl 🙌 |
…eck in model layer
Your checklist for this pull request
Thanks for sending a pull request! Please make sure you click the link above to view the contribution guidelines, then fill out the blanks below.
🚨Please review the guidelines for contributing to this repository.
What does this implement/fix? Explain your changes.
Makes the
graphql_data_is_private
filter a short circuit filter by usingnull
as the default value. A callback could then override this withtrue
orfalse
and that will prevent the defaultis_private()
check running for the model.Does this close any currently open issues?
Fixes #961
Any relevant logs, error output, GraphiQL screenshots, etc?
(If it’s long, please paste to https://ghostbin.com/ and insert the link here.)
Any other comments?
Technically this is a breaking change since the filter signature is changing, but I don't really consider it to be a breaking change since the previous
true
orfalse
context passes as the first param from theis_private()
method probably wasn't really useful in the callback anyways, other than returning it as the default value if certain conditions weren't met, and that functionality still works as it did.Where has this been tested?
Operating System: …
WordPress Version: …