Execute: simplify + speedup#1286
Conversation
| path: ResponsePath, | ||
| result: mixed, | ||
| ): MaybePromise<mixed> { | ||
| // If result is a Promise, apply-lift over completeValue. |
There was a problem hiding this comment.
Do we have a test that shows completing Array<Promise> works?
There was a problem hiding this comment.
@leebyron Yes, it checked here:
graphql-js/src/execution/__tests__/lists-test.js
Lines 167 to 173 in 43ff3e3
| return null; | ||
| } catch (rawError) { | ||
| const error = locatedFieldError(rawError, fieldNodes, path); | ||
| return handleFieldError(error, returnType, exeContext); |
There was a problem hiding this comment.
locatedFieldError and handleFieldError are always called together - should they become a single function?
There was a problem hiding this comment.
@leebyron Yes, you're right. I merged them together 👍
| result, | ||
| ); | ||
| let completed; | ||
| if (isPromise(result)) { |
There was a problem hiding this comment.
I'm concerned moving this out of completeValue may break some scenarios we might not have sufficient test coverage over.
There was a problem hiding this comment.
@leebyron completeValue only called in 3 places:
graphql-js/src/execution/execute.js
Lines 907 to 912 in 43ff3e3
I moved this code to completeValueCatchingError so nothing changed here.
graphql-js/src/execution/execute.js
Lines 919 to 929 in 43ff3e3
This code is called after promise uplift so nothing changed here.
graphql-js/src/execution/execute.js
Line 849 in 43ff3e3
Also nothing is broken here since this call moved to completeValueCatchingError and completeValueCatchingError now handles promise uplift by itself.
535813c to
c4fe200
Compare
|
@leebyron I address review comments. Can you please take a second look? |
|
Really nice work simplifying this! |
* Simplify non-null tests * Remove 'check' function and write test directly * containSubset => deep.equal * Change order of errors because of #1286 * remove excessive async/await
For a feature, I'm working on I needed to understand how
executeis working so I read through its implementation. I notice thatcompleteValueWithLocatedErroris called only fromcompleteValueCatchingErrorand would be simpler to just merge them together.So main reason of this PR is to remove one layout of try/catch & isPromise/then and make error handling more obvious.
To check that I didn't introduce any performance regressions I profiled modified version of introspectionFromSchema-benchmark.js
During this profiling I discovered that hottest function is a fat arrow callback inside
executeFieldsfunction:So I replaced
Array.reducewithforcycle onObject.keysand together with removal ofcompleteValueWithLocatedErrorit resulted in ~15% speedup(9005 ticks vs 7612 ticks), see profile:Performance improvement achieved on a synthetic test and probably wouldn't account for any measurable speedup in most servers. Another small bonus is call stack reduction 1 call (2 calls if a value returned as a promise) for every field or item inside an array.
But most importantly this PR make it easier for a developer to trace how values are resolved/complete inside
execute.