graphql / graphql-spec

GraphQL is a query language and execution engine tied to any backend service.
https://spec.graphql.org
14.31k stars 1.13k forks source link

RFC: deduplicated incremental delivery #1052

Closed yaacovCR closed 9 months ago

yaacovCR commented 1 year ago

Iterating on #1034 and #1026, removed mutation of internal state, event stream management, and the need for subprocedures.

YieldSubsequentPayloads now is passed the entirety of the "state," pending futures, etc, monitors for any changes to pending futures, rebuilds a new "state" representation based on any changes, yields a single result as necessary, and then recursively calls itself to yield remaining results.

[The diff to main might be helpful, but this is built on top of the amazing #742 and so the diff from that branch could be more useful.]

netlify[bot] commented 1 year ago

Deploy Preview for graphql-spec-draft ready!

Name Link
Latest commit a966583d8442ab234d44606911c8cdab37c0dc3f
Latest deploy log https://app.netlify.com/sites/graphql-spec-draft/deploys/65b8a893b199c20008bfb2cc
Deploy Preview https://deploy-preview-1052--graphql-spec-draft.netlify.app/draft
Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

yaacovCR commented 1 year ago

extracted out #1054 from this PR to simply a bit

yaacovCR commented 12 months ago

Conceptually, I've restructured it a bit so that the changes can be summarized as follows:

  1. introduced an "Executing a Field Plan" layer above "Executing a SelectionSet/GroupedFieldSet" where the "Field Plan" refers to the original grouped field set vs. any possible new grouped field sets that need be executed separately (whether they require additional deferral or not)*
  2. {CollectFields()} is changed to: (a) {AnalyzeSelectionSet()} which is responsible for extracting the data from visited fields, new deferred fragments (b) {GetGroupedFieldSets()} which determines the way in which any new deferred grouped field sets must be created, which can be performed prior to execution, same across all members of a list(c) and {GetFieldPlan} which combines the results of these calls.
  3. During execution, actual concrete new deferred fragments and incremental data records are created within {GetPathDependentFieldPlan()}
  4. introduced the {YieldSubsequentPayloads()} algorithm that updates the "incrementalState" internal just to this algorithm so that no illegal mutation is performed
  5. rebased the PR on top of Benjie's https://github.com/graphql/graphql-spec/pull/1039 which changes ExecuteSelectionSet => ExecuteGroupedFieldSet
  6. separated out the necessary edits from @stream and @defer into separate commits, which I think considerably helps with review of the Execution section.
  7. squashed the considerable hx from https://github.com/graphql/graphql-spec/pull/742 to aid in above
yaacovCR commented 11 months ago

Updated to reflect simplification from https://github.com/graphql/graphql-js/pull/3994

yaacovCR commented 9 months ago

closing in favor of #1077, although that PR still describes only algorithmic changes, and additional work from #742 and this PR would have to be pulled in if the approach is adopted.