-
Couldn't load subscription status.
- Fork 1.1k
Lightweight data fetchers #2953
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
Conversation
…ht class -using switch
src/main/java/graphql/GraphQL.java Outdated
| import java.util.ArrayList; | ||
| import java.util.List; | ||
| import java.util.Locale; | ||
| import java.util.Map; |
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.
never used
| executionContext.getGraphQLSchema(), | ||
| executionContext.getCoercedVariables().toMap(), | ||
| executionContext.getGraphQLContext(), | ||
| executionContext.getLocale()); |
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.
These all move down into the supplier of the DataFetchingEnv - they are ONLY needed for it so UNTIL we ask for the DFE - none of this code is run
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.
Its a bit hard to see - open the fill view to see it
| fetchCtx.onCompleted(result, exception); | ||
| if (exception != null) { | ||
| return handleFetchingException(executionContext, environment, exception); | ||
| return handleFetchingException(executionContext, dataFetchingEnvironment.get(), exception); |
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.
we ONLY use the DFE here if we have an exception which is least trodden path
| default T get(GraphQLFieldDefinition fieldDefinition, Object sourceObject, Supplier<DataFetchingEnvironment> environmentSupplier) throws Exception { | ||
| return get(environmentSupplier.get()); | ||
| } | ||
| |
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.
old DataFetchers will be called via delegating back to the old method. Those DFS that implement this method will be called direct
| } | ||
| return fetchedValue; | ||
| } | ||
| |
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.
moved the fetch call into its own method to reduce method complexity
| @PublicApi | ||
| public class InstrumentationFieldFetchParameters extends InstrumentationFieldParameters { | ||
| private final DataFetchingEnvironment environment; | ||
| private final Supplier<DataFetchingEnvironment> environment; |
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.
needs to be a supplier until they ask for it
| this wouldn't disable any validation right, or would it? If we take away looking at solely PropertyDataFetcher, would there be an advantage/disadvantage to introducing a It could be This would maybe confusing because we have two datafetcher methods and one will not be used when isLeightWeight is false. We could offer some default impls to check for it and throw an exception on invalid method calls in combination with invalid isLightWeight for the datafetcher. |
No - this does the same amount of processing as usual. The saving here is that we don't create the full DFE when calling a DataFetcher that uses the new method signature.
The Backdoor is not meant to be permanent code. I created it PURELY so I could have a switch to use in a JMH benchmark. This allows me to test code apth X and then code path Y If this PR got reworked to be accepted then this Backdoor goes away and we would call in via the new method and the old |
| Cool, almost exactly what I thought then 🙂. a ms is a ms |
…ty_fetching # Conflicts: # src/main/java/graphql/schema/PropertyFetchingImpl.java
| Supplier<ExecutableNormalizedField> normalizedFieldSupplier = getNormalizedField(executionContext, parameters, executionStepInfo); | ||
| Supplier<DataFetchingEnvironment> dataFetchingEnvironment = FpKit.intraThreadMemoize(() -> { | ||
| | ||
| // DataFetchingFieldSelectionSet and QueryDirectives is a supplier of sorts - eg a lazy pattern |
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.
DFE creation is now one big supplier
| * and the related field will have a value of {@code null} in the result. | ||
| */ | ||
| T get(GraphQLFieldDefinition fieldDefinition, Object sourceObject, Supplier<DataFetchingEnvironment> environmentSupplier) throws Exception; | ||
| } |
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.
Added a new interface to keep Andi happy and to better delineate what the data fetcher does. Is it light or heavy?
Its MUST be a DataFetcher however because the CodeRegistry requires a DataFetcher when registered
…ty_fetching # Conflicts: # src/main/java/graphql/schema/PropertyFetchingImpl.java

The idea here is to make the object creation for DataFetchers even lighter.
This is basically here for PropertyDataFetcher to implement since it ONLY needs the source really to get property values from.
The premise is that we avoid allocating all the objects that go into a DataFetchingEnvironment for simple property fetches
So for this benchmark - this IS slightly faster - the more simple property fetches there are, the more savings to be made
This benchmark biases towards property fetches on purpose