Skip to content
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

Simplify collectFields for @defer & @stream #3982

Closed

Conversation

robrichard
Copy link
Contributor

No description provided.

Copy link

netlify bot commented Nov 6, 2023

Deploy Preview for compassionate-pike-271cb3 ready!

Name Link
🔨 Latest commit 9472777
🔍 Latest deploy log https://app.netlify.com/sites/compassionate-pike-271cb3/deploys/655e23dd985d42000813030a
😎 Deploy Preview https://deploy-preview-3982--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 configuration.

Copy link

github-actions bot commented Nov 6, 2023

Hi @robrichard, 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

@robrichard robrichard force-pushed the defer-stream-collectFields branch 2 times, most recently from 1648183 to b520452 Compare November 6, 2023 21:14
@yaacovCR
Copy link
Contributor

yaacovCR commented Nov 7, 2023

Hey @robrichard!

Could we take a look at this rebased on #3984 after that is reviewed/merged => ideally there would be no/minimal test changes at that point...

@robrichard robrichard force-pushed the defer-stream-collectFields branch 3 times, most recently from 0da8e48 to 355ca68 Compare November 8, 2023 17:56
yaacovCR added a commit that referenced this pull request Nov 9, 2023
current loop assumes that the first analyzed DeferredFragmentRecord has been released as pending and thereofre has an `id`, which happens to be the case in this scenario, but is not reliable, uncovered by #3982.

Demonstrates the peril of `!` which might point to requiring additional types, but we can leave that for a different PR.

Another option is to include an `invariant` call -- that should be unnecessary, but would indeed be safer.
@robrichard robrichard force-pushed the defer-stream-collectFields branch 2 times, most recently from a8994d9 to 9c5ba6e Compare November 9, 2023 20:10
src/execution/execute.ts Outdated Show resolved Hide resolved
we only use the parent because masking analysis done differently
for (const fieldDetail of fieldDetails) {
if (fieldDetail.deferUsage != null) {
deferUsageSet.add(fieldDetail.deferUsage);
newDeferUsages.add(fieldDetail.deferUsage);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the current implementation, collectFields() returns:

  groupedFieldSet: GroupedFieldSet;
  newGroupedFieldSetDetails: Map<DeferUsageSet, GroupedFieldSetDetails>;
  newDeferUsages: ReadonlyArray<DeferUsage>;

I just realized that in addition to removing newGroupedFieldSetDetails, this PR also removes newDeferUsages and so your list of potential newDeferUsages is going to include every field nested under every defer. Because you have changed addDeferredFragments to check the deferMap before actually creating a new Deferred Fragment, you don't end up with duplicate records, but there is a lot of duplicate effort.

Maybe it might make sense to allow collectFields() to return newDeferUsages again and just get rid of newGroupedFieldSetDetails?

} else {
let deferredGroup = deferredGroups.find((group) =>
isSameSet(group.deferUsageSet, deferUsageSet),
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because masking here is done differently, this find is not necessarily stable, consider the operation:

query HeroNameQuery {
        ... @defer(label: "DeferID") {
          hero {
            id
          }
        }
        ... @defer(label: "DeferName") {
          hero {
            name
            lastName
            ... @defer {
              lastName
            }
          }
        }
      }

hero is used in two parallel defers, with the id subfield present in DeferID and both name and lastName present in DeferName. The subfields of hero should therefore yield two new grouped field sets, but according to this algorithm, it would yield three, as the additional superfluous defer would still be counted and so the deferUsageSet for lastName would actually be different for name.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to fix this, you may need to bring back ancestors on DeferUsage

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I raised an alternative approach in #3994.

yaacovCR added a commit to yaacovCR/graphql-executor that referenced this pull request Dec 8, 2023
minimizes changes to CollectFields a la graphql#3982 but still creates a single memoized incremental field plan per list item.
yaacovCR added a commit to yaacovCR/graphql-executor that referenced this pull request Dec 8, 2023
minimizes changes to CollectFields a la graphql#3982 but still creates a single memoized incremental field plan per list item.
yaacovCR added a commit that referenced this pull request Dec 16, 2023
minimizes the changes to `CollectFields` required for incremental delivery (inspired by #3982) -- but retains a single memoized incremental field plan per list item.
@robrichard robrichard closed this Dec 16, 2023
yaacovCR added a commit to yaacovCR/graphql-executor that referenced this pull request Dec 16, 2023
minimizes the changes to `CollectFields` required for incremental delivery (inspired by graphql#3982) -- but retains a single memoized incremental field plan per list item.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants