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

fix(federation): correct order of @skip and @include conditions on the same selection #6137

Merged
merged 4 commits into from
Oct 11, 2024

Conversation

goto-bus-stop
Copy link
Member

@goto-bus-stop goto-bus-stop commented Oct 10, 2024

PR #6120 was the wrong solution. JS doesn't actually maintain the order
of the conditions, like I thought. Instead, it always puts @skip first
and @include second, the opposite of what Rust was doing.

https://github.com/apollographql/federation/blob/cc4573471696ef78d04fa00c4cf8e5c50314ba9f/query-graphs-js/src/pathContext.ts#L13-L33

The queries I was testing with just happened to pass in #6120.

This changes the implementation of Conditions::from_directives to
pick the directives out manually instead of iterating. Technically, this
does two iterations of the directive list...but, the code is a bit
simpler, I think.

In the second commit I do a small refactor to replace the is_negated
boolean by a ConditionKind enum. I found it quite tricky to
constantly translate the skip/include concepts to negation or not
while reading the code, so I hope this simplifies it a bit.

…n the same selection

PR #6120 was the wrong solution. JS doesn't actually maintain the order
of the conditions, like I thought. Instead, it always puts `@skip` first
and `@include` second, the opposite of what Rust was doing.

The queries I was testing with just happened to pass in #6120.

This changes the implementation of `Conditions::from_directives` to
pick the directives out manually instead of iterating. Technically, this
does two iterations of the directive list...but, the code is a bit
simpler, I think.
@svc-apollo-docs
Copy link
Collaborator

svc-apollo-docs commented Oct 10, 2024

✅ Docs Preview Ready

No new or changed pages found.

Copy link
Contributor

@goto-bus-stop, please consider creating a changeset entry in /.changesets/. These instructions describe the process and tooling.

Copy link
Contributor

@duckki duckki left a comment

Choose a reason for hiding this comment

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

Just one question/request. Otherwise, I like the refactoring!

"skip" => true,
_ => continue,

if let Some(skip) = directives.get("skip") {
Copy link
Contributor

Choose a reason for hiding this comment

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

It appears that the directives may have multiple skip/include directive applications. This will handle only one of each type.

Copy link
Member

Choose a reason for hiding this comment

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

Per the spec @skip and @include are not repeatable so they cannot appear multiple times.

Ok(Self::from_variables(variables))
}

// TODO(@goto-bus-stop): what exactly is the difference between this and `Self::merge`?
Copy link
Contributor

Choose a reason for hiding this comment

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

Indeed, merge makes more sense. It's unclear why update_with is so loose in the Boolean(false) cases.

Copy link
Member Author

Choose a reason for hiding this comment

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

I played around a bit more with this code and learned what this actually does.

If you nested condition nodes, update_with() will remove from the inner node those conditions that were already matched by the outer node. So it's very different from merge() :)

I'll add a doc comment for that

@duckki duckki merged commit 871c3c7 into dev Oct 11, 2024
14 checks passed
@duckki duckki deleted the renee/ROUTER-799-followup branch October 11, 2024 00:34
@router-perf
Copy link

router-perf bot commented Oct 11, 2024

CI performance tests

  • connectors-const - Connectors stress test that runs with a constant number of users
  • const - Basic stress test that runs with a constant number of users
  • demand-control-instrumented - A copy of the step test, but with demand control monitoring and metrics enabled
  • demand-control-uninstrumented - A copy of the step test, but with demand control monitoring enabled
  • enhanced-signature - Enhanced signature enabled
  • events - Stress test for events with a lot of users and deduplication ENABLED
  • events_big_cap_high_rate - Stress test for events with a lot of users, deduplication enabled and high rate event with a big queue capacity
  • events_big_cap_high_rate_callback - Stress test for events with a lot of users, deduplication enabled and high rate event with a big queue capacity using callback mode
  • events_callback - Stress test for events with a lot of users and deduplication ENABLED in callback mode
  • events_without_dedup - Stress test for events with a lot of users and deduplication DISABLED
  • events_without_dedup_callback - Stress test for events with a lot of users and deduplication DISABLED using callback mode
  • extended-reference-mode - Extended reference mode enabled
  • large-request - Stress test with a 1 MB request payload
  • no-tracing - Basic stress test, no tracing
  • reload - Reload test over a long period of time at a constant rate of users
  • step-jemalloc-tuning - Clone of the basic stress test for jemalloc tuning
  • step-local-metrics - Field stats that are generated from the router rather than FTV1
  • step-with-prometheus - A copy of the step test with the Prometheus metrics exporter enabled
  • step - Basic stress test that steps up the number of users over time
  • xlarge-request - Stress test with 10 MB request payload
  • xxlarge-request - Stress test with 100 MB request payload

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.

4 participants