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
perf improvements for fragment cycles validation #2786
perf improvements for fragment cycles validation #2786
Conversation
@@ -81,31 +81,6 @@ class NoFragmentCyclesTest extends Specification { | |||
errorCollector.getErrors().isEmpty() | |||
} | |||
|
|||
|
|||
def "circular fragments"() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this test is a duplicate of "no co-recursive spreads in floating fragments"
errorCollector.containsValidationError(ValidationErrorType.FragmentCycle) | ||
} | ||
|
||
def 'no spreading itself directly'() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this test is a duplicate of "no self-spreading in floating fragments"
don't recheck fragments that have been checked anywhere in the fragments tree, not just the immediate ancestors
# Conflicts: # src/main/java/graphql/validation/rules/NoFragmentCycles.java # src/test/groovy/graphql/validation/rules/NoFragmentCyclesTest.groovy # src/test/java/benchmark/ValidatorBenchmark.java
FYI @jbellenger I updated your branch and resolved merge conflicts to get this ready for release. Thanks so much! |
We've observed that some of our real-world queries are taking seconds to validate.
When profiling these queries, it looks like the validation time is dominated by the NoFragmentCycles rule.
This PR reworks NoFragmentCycles to not traverse into fragments that have already been visited anywhere in a fragments transitive dependencies. This is similar behavior to the graphql-js implementation and adheres to 5.5.2.2 Fragment spreads must not form cycles. This PR should result in no external behavioral changes.
This change improves the validation time for one of our fragment-heavy queries by over 100x.
I've added an anonymized version of our schema and query as new resources, which are measured below as a new "manyFragments" benchmark:
Before:
After:
Side note:
I had some issues using Anonymizer with built-in directives. It seemed to generate assertion errors when
@include
was applied to a selection set, like:I didn't have the context to understand what Anonymizer expected in this case so I didn't dig into it too much, though I'm happy to privately share a query+schema that triggered this if that helps.