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

feat: generate operation names for subgraph fetches #1550

Merged

Conversation

lennyburdette
Copy link
Contributor

Addresses #1544, #195, #146

@codesandbox-ci
Copy link

codesandbox-ci bot commented Mar 1, 2022

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

@lennyburdette
Copy link
Contributor Author

i didn't change any the feature tests but i'm happy to do so if my approach is acceptable

@lennyburdette lennyburdette force-pushed the fetchnode-operation-names branch from 93bb0a5 to 214cf38 Compare March 1, 2022 01:45
@pcmanus
Copy link
Contributor

pcmanus commented Mar 1, 2022

Had a fairly quick scan, but the general approach looks good to me.

I do think the handling of unnamed operation doesn't work just right, as it ends up with operation named like undefined_accounts_0 and I believe your intend was that it would be UnnamedOperation_accounts_0.

And as an aside on that front, not sure I'm a fan of UnnamedOperation_accounts_0. Clearly a small point but I'd consider either:

  1. just accounts_0. Not sure a somewhat random hard-coded string adds much here (and it makes query plan bigger, even if that's a fairly minor concern).
  2. not having query names in the query plan at all (so like we do today) if the original query doesn't have one. One reason I though of that is that it would save us from having to update plenty of tests, and there's a logic to it I guess. But I suspect that some users may want operation names in query plan but without having a simple way to force "input" operations to have a names, so not certain this is a great solution.

@lennyburdette lennyburdette force-pushed the fetchnode-operation-names branch from 214cf38 to c7cecf7 Compare March 1, 2022 18:02
@lennyburdette
Copy link
Contributor Author

Excellent points! I talked to the customer and he thought that option 2 sounds right. I updated the code to drop operation names if the original request does not have one.

Should I start updating all the tests? Or is there anything else worth discussing/addressing first?

@pcmanus
Copy link
Contributor

pcmanus commented Mar 1, 2022

Should I start updating all the tests? Or is there anything else worth discussing/addressing first?

I'll do a final review pass on the final version, but I don't have anything else to bring. Seems like a great improvement with little downsides (especially if we use option 2 above which gives a de-factor option to "disable" the operation naming if for some reason someone wants that (can't really think of a reason but ...)). Re-tests, hopefully you don't have to change that much of them if you switch to "option 2" above since I believe most tests use unnamed operations (and so won't be impacted anymore).

@lennyburdette lennyburdette force-pushed the fetchnode-operation-names branch 2 times, most recently from 381a638 to d37800d Compare March 1, 2022 23:32
@lennyburdette lennyburdette changed the title DRAFT feat: generate operation names for subgraph fetches feat: generate operation names for subgraph fetches Mar 1, 2022
@lennyburdette lennyburdette marked this pull request as ready for review March 1, 2022 23:32
@lennyburdette lennyburdette force-pushed the fetchnode-operation-names branch from d37800d to 8af25ee Compare March 2, 2022 00:32
@lennyburdette lennyburdette force-pushed the fetchnode-operation-names branch from 8af25ee to 0ae9cd5 Compare March 2, 2022 00:34
@lennyburdette
Copy link
Contributor Author

I can't add reviewers to the PR but I think this is good to go.

@cpeacock cpeacock requested a review from pcmanus March 2, 2022 20:03
@cpeacock
Copy link
Contributor

cpeacock commented Mar 2, 2022

Added @pcmanus since he looked at it previously for the morning (if he can't get to it I'll look on Friday).

Copy link
Contributor

@pcmanus pcmanus left a comment

Choose a reason for hiding this comment

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

Lgtm, thanks!

@pcmanus pcmanus merged commit e73c15a into apollographql:main Mar 3, 2022
@@ -1213,7 +1219,8 @@ Scenario: supports multiple root mutations
"password"
],
"operationKind": "mutation",
"operation": "mutation($username:String!$password:String!){login(username:$username password:$password){__typename id}}"
"operation": "mutation LoginAndReview_accounts_0($username:String!$password:String!){login(username:$username password:$password){__typename id}}",
"operationName": "LoginAndReview_accounts_0"
Copy link
Member

@abernix abernix Mar 3, 2022

Choose a reason for hiding this comment

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

Very thankful you chose to add operationName in here! (In a general sense, not just on this snapshot in particular!)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍🏻 I had to in order to provide the operationName query param on the request, because that's probably what observability tools look at (instead of parsing the operation doc).

Copy link
Member

Choose a reason for hiding this comment

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

For context as to why i'm glad: it's only recently that we started adding operationKind in there, which enabled the router to make Good decisions without needing to — in the same spirit as you're describing — re-parse the operation.

@abernix
Copy link
Member

abernix commented Mar 3, 2022

I closed the related issues above referenced in the original post which weren't auto-closed. I also found #395, but I wasn't sure what the third reference was — #146 doesn't look relevant.

@pcmanus Are you keeping a running CHANGELOG for things like this?

@lennyburdette lennyburdette deleted the fetchnode-operation-names branch March 3, 2022 17:40
@@ -1405,7 +1418,8 @@ Scenario: multiple root mutations with correct service order
],
"variableUsages": [],
"operationKind": "query",
"operation": "query($representations:[_Any!]!){_entities(representations:$representations){...on User{reviews{product{__typename ...on Book{__typename isbn}...on Furniture{upc}}}}}}"
"operation": "query LoginAndReview_reviews_2($representations:[_Any!]!){_entities(representations:$representations){...on User{reviews{product{__typename ...on Book{__typename isbn}...on Furniture{upc}}}}}}",
"operationName": "LoginAndReview_reviews_2"
Copy link
Member

@abernix abernix Mar 3, 2022

Choose a reason for hiding this comment

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

@pcmanus @lennyburdette Picking a random place to leave this post-merge thought — would it make sense to use double-underscores as the delimiter to create a more predictable pattern for parsing and to avoid name-conflicts across operation + subgraph names? Mostly just because it seems not completely unlikely that both an operation and a subgraph might use _ on its own and, while not forbidden, much less likely that someone would use __. We could even forbid __ as a valid graph name (and probably should or may already have a enforced character set somewhere?).

Just trying to avoid the case of two things end up being exactly equal. If my service name is movie_titles and my operation is get_movie_titles, I would have get_movie_titles_movie_titles_0. It would be nice if I could split on something that's: forbidden in the service name and therefore reliably delineates parts, and get_movie_titles__movie_titles__0 would get that.

It was similarly intentional that I'd suggested (in addition to the above) prefixing with __ in the (Slack) thread where this initially came up — just to indicate the generated-ness and avoid these name clashes, just in case people use these operations downstream in meaningful ways.

Also happy to ticket this for follow-up. Or not, depending on thoughts.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

no strong feelings either way. i went with fewer characters but four extra underscores (two in the operationName query param and two in the operation document) isn't a huge deal.

Copy link
Member

Choose a reason for hiding this comment

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

I also like the idea of the double underscore separator, and if we are not already we should enforce that subgraphs have to start and end with a number or letter

@pcmanus
Copy link
Contributor

pcmanus commented Mar 7, 2022

Fyi, just noticed that we include the subgraph name here and that we enforce very little kind of limitations on subgraph names so this patch can currently very easily create invalid query names and break things. I'll write a followup patch for it. I might sneak in the double underscore change discussed above as well since it seems to be overall favored.

@pcmanus pcmanus mentioned this pull request Mar 7, 2022
@trevor-scheer
Copy link
Member

Should this be ported to the version-0.x branch?

@lennyburdette
Copy link
Contributor Author

this patch can currently very easily create invalid query names and break things

if the original operation name name is bad, wouldn't things break in the validation phase before getting to the query planner?

Should this be ported to the version-0.x branch?

both customers i've talked to about this are fine with it being a 2.0-only improvement, but i'm sure others would be happy if you did!

@pcmanus
Copy link
Contributor

pcmanus commented Mar 8, 2022

if the original operation name name is bad, wouldn't things break in the validation phase

Yes, but it's not the original operation name the issue, it's the subgraph name, which is also included (as 2nd element) and is not otherwise validated. Anyway, #1568 has been pushed to fix it and has been merged (sorry for not waiting too long on feedback on that one but we want to do a new release very soon and this was a serious break so wanted to get it fixed asap).

@chrskrchr
Copy link

Should this be ported to the version-0.x branch?

both customers i've talked to about this are fine with it being a 2.0-only improvement, but i'm sure others would be happy if you did!

Any word on if/when this change will be backported to 0.x? Would love to rip out our custom operation propagation code.

@dakshas
Copy link

dakshas commented Nov 30, 2022

Hi folks! Can someone explain why the counter appended to the operation name is necessary ?
The counter makes tracking metrics slightly more complicated as now we need to use a wildcard to account for the changing counter values. Although unlikely, I'm worried the wildcard might lead to erroneous matching and there by incorrect metric calculations in cases where some operation names are substrings of other operation names.

I realize I can overwrite the operationName in my willSendRequest method, but just want to know more about what the original intention of adding the counter is.

@pcmanus
Copy link
Contributor

pcmanus commented Nov 30, 2022

why the counter appended to the operation name is necessary ?

Query plans can easily have multiple different fetches to the same subgraphs. Without the counter, each of those fetches, which can very different queries (say, they may fetch completely different entity types), would have the same name. Which might be acceptable in some use cases, but isn't in many others. Typically, if you use the operation name as an identifier for metrics, not having a counter would lump together the metrics of potentially fairly unrelated subgraph queries.

@dakshas
Copy link

dakshas commented Nov 30, 2022

@pcmanus thank you for the prompt reply!

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.

8 participants