Skip to content

incremental delivery without branching#3862

Closed
yaacovCR wants to merge 5 commits intographql:mainfrom
yaacovCR:squashed
Closed

incremental delivery without branching#3862
yaacovCR wants to merge 5 commits intographql:mainfrom
yaacovCR:squashed

Conversation

@yaacovCR
Copy link
Copy Markdown
Contributor

@yaacovCR yaacovCR commented Mar 12, 2023

this version of incremental delivery works without branching, solving the issue raised by @Keweiqu

see discussion here: graphql/defer-stream-wg#65

UPDATE: this is now ready for review

** huge thanks to @Urigo and @dotansimha of the guild for sponsoring my open-source work on this. **

@netlify
Copy link
Copy Markdown

netlify Bot commented Mar 12, 2023

Deploy Preview for compassionate-pike-271cb3 ready!

Name Link
🔨 Latest commit 7df0bfc
🔍 Latest deploy log https://app.netlify.com/sites/compassionate-pike-271cb3/deploys/64442a6d41ec9200077792f8
😎 Deploy Preview https://deploy-preview-3862--compassionate-pike-271cb3.netlify.app
📱 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 settings.

@github-actions
Copy link
Copy Markdown

Hi @yaacovCR, I'm @github-actions bot happy to help you with this PR 👋

Supported commands

Please post this commands in separate comments and only one per comment:

  • @github-actions run-benchmark - Run benchmark comparing base and merge commits for this PR
  • @github-actions publish-pr-on-npm - Build package from this PR and publish it on NPM

Comment thread src/execution/execute.ts Fixed
@yaacovCR yaacovCR force-pushed the squashed branch 14 times, most recently from d8ae014 to bcfad72 Compare March 15, 2023 13:41
Comment thread src/execution/execute.ts Fixed
@yaacovCR yaacovCR force-pushed the squashed branch 12 times, most recently from e2e397f to 51fa808 Compare March 19, 2023 19:01
@yaacovCR
Copy link
Copy Markdown
Contributor Author

I have added a commit to show how deduplication can work.

Error boundaries are preserved. In particular:

(A) Deduplication

For the following operation:

      query {
        a {
          b {
            c {
              d
            }
            ... @defer {
              e {
                f
              }
            }
          }
        }
        ... @defer {
          a {
            b {
              e {
                f
              }
            }
          }
          g {
            h
          }
        }
      }

...the following payloads are generated:

[
      {
        data: {
          a: {
            b: {
              c: {
                d: 'd',
              },
            },
          },
        },
        hasNext: true,
      },
      {
        incremental: [
          {
            data: {
              e: {
                f: 'f',
              },
            },
            path: ['a', 'b'],
          },
          {
            data: {
              g: {
                h: 'h',
              },
            },
            path: [],
          },
        ],
        hasNext: false,
      },
    ]

(B) Null Bubbling is a Deduplication Exception

For the following operation:

      query {
        ... @defer {
          a {
            someField
            b {
              c {
                slowNonNullErrorField
              }
            }
          }
        }
        a {
          ... @defer {
            b {
              c {
                d
              }
            }
          }
        }
      }

...the following payloads are generated:

[
      {
        data: {
          a: {},
        },
        hasNext: true,
      },
      {
        incremental: [
          {
            data: {
              b: {
                c: {
                  d: 'd',
                },
              },
            },
            path: ['a'],
          },
        ],
        hasNext: true,
      },
      {
        incremental: [
          {
            data: {
              a: {
                b: {
                  c: null,     //    <==== note that c is sent as null even though sent already
                },
                someField: 'someField',
              },
            },
            errors: [
              {
                message:
                  'Cannot return null for non-nullable field c.slowNonNullErrorField.',
                locations: [{ line: 8, column: 17 }],
                path: ['a', 'b', 'c', 'slowNonNullErrorField'],
              },
            ],
            path: [],
          },
        ],
        hasNext: false,
      },
    ]

(C) Null Bubbling Preserving Error Boundaries

For the following operation:

      query {
        ... @defer {
          a {
            someField
            b {
              c {
                nonNullErrorField
              }
            }
          }
        }
        a {
          ... @defer {
            b {
              c {
                d
              }
            }
          }
        }
      }

...the following payloads are generated:

[
      {
        data: {
          a: {},
        },
        hasNext: true,
      },
      {
        incremental: [
          {
            data: {
              a: {
                b: {
                  c: null,
                },
                someField: 'someField',
              },
            },
            errors: [
              {
                message:
                  'Cannot return null for non-nullable field c.nonNullErrorField.',
                locations: [{ line: 8, column: 17 }],
                path: ['a', 'b', 'c', 'nonNullErrorField'],
              },
            ],
            path: [],
          },
          {
            data: {
              b: {
                c: {                           //    <==== note that c is sent with data
                  d: 'd',                     //    <==== even though the other payload bubbled up
                },
              },
            },
            path: ['a'],
          },
        ],
        hasNext: false,
      },
    ]

@yaacovCR
Copy link
Copy Markdown
Contributor Author

yaacovCR commented Apr 4, 2023

Moved deduplication out of this pr for now as per latest discussion…

Extracted a few commits that start to minimize the diff….

@yaacovCR yaacovCR force-pushed the squashed branch 2 times, most recently from 562c6e9 to d581d89 Compare April 5, 2023 01:36
@yaacovCR yaacovCR force-pushed the squashed branch 4 times, most recently from 2236283 to c383eaf Compare April 17, 2023 21:08
@yaacovCR
Copy link
Copy Markdown
Contributor Author

This PR has been updated to remove branching while retaining the original publisher.

@yaacovCR
Copy link
Copy Markdown
Contributor Author

This PR has been updated to remove the stream refactoring that reduces ticks, so as to reduce the diff to facilitate review.

@yaacovCR
Copy link
Copy Markdown
Contributor Author

@robrichard @IvanGoncharov @graphql/graphql-js-reviewers ready for review

@yaacovCR
Copy link
Copy Markdown
Contributor Author

@benjie

@yaacovCR
Copy link
Copy Markdown
Contributor Author

updated with a new test and some offline feedback from @robrichard

the labels were only checked to be unique (and only have to be unique) in combination with the path at which they are used

execute was never using the keys, just the values
@yaacovCR
Copy link
Copy Markdown
Contributor Author

yaacovCR commented May 8, 2023

closing in favor of #3886

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

PR: breaking change 💥 implementation requires increase of "major" version number

Projects

None yet

Development

Successfully merging this pull request may close these issues.

No entiendo nada

2 participants