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 apollo-engine-reporting operationName capturing #2899

Merged
merged 1 commit into from
Jun 24, 2019

Conversation

glasser
Copy link
Member

@glasser glasser commented Jun 21, 2019

The full query caching change (#2437) intended to introduce didResolveOperation
to the old graphql-extensions API used by apollo-engine-reporting ("backporting"
it from the newer plugin API). However, that change accidentally forgot to
invoke didResolveOperation from the request pipeline! This meant that the
operation name never got reported.

The change was backed out in #2557. But this unfortunately re-introduced the
exact bug that the change in #2437 was intended to fix: operationName was no
longer set when a result is served from the cache! Additionally, it was not set
if a plugin didResolveOperation call threw, which is what happens when the
operation registry plugin forbids an operation.

While we could have fixed this by reintroducing the didResolveOperation
extension API, there would be a subtle requirement that the
apollo-engine-reporting extension didResolveOperation be run before the
possibly-throwing operation registry didResolveOperation.

So instead, @abernix implemented #2711. This used requestContext.operationName
as a fallback if neither executionDidStart nor willResolveField gets
called. This will be set if the operation properly parsed, validates, and either
has a specified operationName that is found in the document, or there is no
specified operationName and there is exactly one operation in the document and
it has a name.

(Note that no version of this code ever sent the user-provided operationName in
case of parse or validation errors.)

The existing code is correct, but this PR cleans up a few things:

  • [release-2.5.0] Fix missing operationName in apollo-engine-reporting. #2557 reverted the one implementation of the didResolveOperation extension
    API, and Full query response cache plugin #2437 accidentally didn't contain any callers of the API, but it
    was still declared on GraphQLExtension and GraphQLExtensionStack. This PR
    removes those declarations (which have never been useful).

  • We currently look for the operation name in willResolveField. But in any case
    where fields are successfully being resolved, the pipeline must have managed
    to successfully resolve the operation and set requestContext.operationName. So
    we don't actually need the willResolveField code, because the "fallback" in
    the requestDidStart end-callback will have the same value. So take this code
    away. (This change is the motivation for this PR; for federation metrics I'm
    trying to disengage the "calculate times for fields" part of trace generation
    from the rest of it.)

  • Fix the comment in "requestDidEnd" that implied incorrectly that
    requestContext.operationName was the user-provided name rather than the
    pipeline-calculated name. Be explicit both there and in requestPipeline.ts
    that we are relying on the fact that the RequestContext passed to
    requestDidStart is mutated to add operationName before its end handler is
    called.

This change is intended to be a no-op change (other than the removal of the
never-used APIs).

@glasser glasser requested a review from abernix June 21, 2019 22:17
@glasser glasser force-pushed the glasser/simplify-aer-operation-name branch from 1819edb to ab8a250 Compare June 21, 2019 22:26
Copy link
Member

@abernix abernix left a comment

Choose a reason for hiding this comment

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

LGTM! Thank you so much for taking the time to unwind this!

The full query caching change (#2437) intended to introduce didResolveOperation
to the old graphql-extensions API used by apollo-engine-reporting ("backporting"
it from the newer plugin API). However, that change accidentally forgot to
invoke didResolveOperation from the request pipeline! This meant that the
operation name never got reported.

The change was backed out in #2557. But this unfortunately re-introduced the
exact bug that the change in #2437 was intended to fix: operationName was no
longer set when a result is served from the cache! Additionally, it was not set
if a *plugin* didResolveOperation call threw, which is what happens when the
operation registry plugin forbids an operation.

While we could have fixed this by reintroducing the didResolveOperation
extension API, there would be a subtle requirement that the
apollo-engine-reporting extension didResolveOperation be run before the
possibly-throwing operation registry didResolveOperation.

So instead, @abernix implemented #2711. This used `requestContext.operationName`
as a fallback if neither executionDidStart nor willResolveField gets
called. This will be set if the operation properly parsed, validates, and either
has a specified operationName that is found in the document, or there is no
specified operationName and there is exactly one operation in the document and
it has a name.

(Note that no version of this code ever sent the user-provided operationName in
case of parse or validation errors.)

The existing code is correct, but this PR cleans up a few things:

- #2557 reverted the one *implementation* of the didResolveOperation extension
   API, and #2437 accidentally didn't contain any *callers* of the API, but it
   was still declared on GraphQLExtension and GraphQLExtensionStack. This PR
   removes those declarations (which have never been useful).

- We currently look for the operation name in willResolveField. But in any case
  where fields are successfully being resolved, the pipeline must have managed
  to successfully resolve the operation and set requestContext.operationName. So
  we don't actually need the willResolveField code, because the "fallback" in
  the requestDidStart end-callback will have the same value. So take this code
  away. (This change is the motivation for this PR; for federation metrics I'm
  trying to disengage the "calculate times for fields" part of trace generation
  from the rest of it.)

- Fix the comment in "requestDidEnd" that implied incorrectly that
  requestContext.operationName was the user-provided name rather than the
  pipeline-calculated name. Be explicit both there and in requestPipeline.ts
  that we are relying on the fact that the RequestContext passed to
  requestDidStart is mutated to add operationName before its end handler is
  called.

This change is intended to be a no-op change (other than the removal of the
never-used APIs).
@glasser glasser force-pushed the glasser/simplify-aer-operation-name branch from ab8a250 to bc0ae82 Compare June 24, 2019 20:12
@glasser glasser merged commit f3ae806 into master Jun 24, 2019
@glasser glasser deleted the glasser/simplify-aer-operation-name branch June 24, 2019 20:16
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 22, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants