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

refactor: Graph Manager (Engine) reporting "extensions" become "plugins". #3998

Merged

Conversation

abernix
Copy link
Member

@abernix abernix commented Apr 16, 2020

This PR depends on #3988 and #3996 (this PR is targeted to merge into the latter). It is part of an initiative to deprecate all internal usages of the graphql-extensions API. Similar work can be seen in the work done to migrate the apollo-tracing extension (#3991) and the apollo-cache-control extention (#3997). Similar to those commits, this introduces:

  1. A plugin utilized by the agent's newExtension method which generates a plugin wired up to the mechanism which transmit metrics to Apollo Graph Manager ingress. This plugin is meant to replicate the behavior of the EngineReportingExtension class.
  2. A federatedPlugin (i.e. exported on the main module of the apollo-engine-reporting package), meant to replicate the behavior of the EngineFederatedTracingExtension class. This plugin provides the functionality currently used by implementing services in a federated configuration to include the Base64-encoded protobuf trace on the ftv1 extension of responses from the implementing service. This encoded extension data is consumed by the Apollo Gateway when received from an implementing service.

Like the other PRs above, the delta of the commits seemed more confusing by allowing a natural diff to be made of it, so I've left the extensions in place alongside the new plugins in the first commit so they can be compared - presumably side-by-side in an editor - on the same commit. A subsequent commit in this PR removes the existing extensions, so you can choose whether you'd like to view it in its totality or commit by commit.

…ns".

Similar to 6009d8a (#3991) and 68cbc93 (#3997), which migrated the
tracing and cache-control extensions to the (newer) request pipeline plugin
API, this commit introduces:

 - Internally, a `plugin` named export which is utilized by the `agent`'s
   `newExtension` method to provide a plugin which is instrumented to
   transmit metrics to Apollo Graph Manager.  This plugin is meant to
   replicate the behavior of the `EngineReportingExtension` class which,
   as of this commit, still lives besides it.
 - Externally, a `federatedPlugin` exported on the main module of the
   `apollo-engine-reporting` package.  This plugin is meant to replicate the
   behavior of the `EngineFederatedTracingExtension` class (also exported on
   the main module) which, again as of this commit, still lives besides it!

Again, the delta of the commits seemed more confusing by allowing a natural
`diff` to be made of it, I've left the extensions in place so they can be
compared - presumably side-by-side in an editor - on the same commit.  An
(immediate) subsequent commit will remove the extension.
This fixes the failing tests which correctly surfaced on the last commit.

Previously, prior to the new plugin API, the Apollo Engine Reporting
mechanism was implemented using `graphql-extensions`, the API for which
didn't invoke `requestDidStart` until _after_ APQ had been negotiated.

The new plugin API starts its `requestDidStart` _before_ APQ validation and
various other assertions which weren't included in the `requestDidStart`
life-cycle, even if they perhaps should be in terms of error reporting.

The new plugin API is able to properly capture such errors within its
`didEncounterErrors` lifecycle hook (thanks to
#3614, which
intentionally captures these failures so plugin authors can accurately react
to them), however, for behavioral consistency reasons, we will still
special-case those errors and maintain the legacy behavior to avoid a
breaking change.  We can reconsider this in a future version of Apollo
Engine Reporting (AS3, perhaps!).

Ref: #3614
Ref: #3627
Ref: #3638
The plugin implementation brought in de7ba72 supersedes the need for
this implementation!
@abernix abernix self-assigned this Apr 16, 2020
@abernix abernix added 🔌 plugins Relates to the request pipeline plugin API 🧬 graphql-extensions labels Apr 16, 2020
@abernix abernix added this to the Release 2.13.0 milestone Apr 16, 2020
@abernix abernix requested a review from glasser April 16, 2020 17:36
@glasser
Copy link
Member

glasser commented Apr 23, 2020

Sorry for the delay. Targeting tomorrow, high priority.

@glasser
Copy link
Member

glasser commented Apr 23, 2020

Ugh, I really meant to get to this today, but time is a slippery thing.

Copy link
Member

@glasser glasser left a comment

Choose a reason for hiding this comment

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

Really glad you're doing this! And thanks for making this so reviewable.

packages/apollo-server-core/src/ApolloServer.ts Outdated Show resolved Hide resolved
packages/apollo-engine-reporting/src/federatedExtension.ts Outdated Show resolved Hide resolved
packages/apollo-engine-reporting/src/federatedExtension.ts Outdated Show resolved Hide resolved
packages/apollo-engine-reporting/src/federatedExtension.ts Outdated Show resolved Hide resolved
packages/apollo-engine-reporting/src/extension.ts Outdated Show resolved Hide resolved
packages/apollo-engine-reporting/src/plugin.ts Outdated Show resolved Hide resolved
packages/apollo-engine-reporting/src/plugin.ts Outdated Show resolved Hide resolved
packages/apollo-engine-reporting/src/extension.ts Outdated Show resolved Hide resolved
@abernix abernix force-pushed the abernix/migrate-engine-reporting-exts-to-plugin-api branch from a3c378b to 8ca5d11 Compare April 28, 2020 12:59
As noted in review within [[1]], there wasn't really a compelling reason for
this to be kept separately from the other tree-building bits which existed
within `ensurePreflight`.

[1]: #3998 (comment)
…tring`.

The use of `document` and `source` is the standard within the plugin API and
the request pipeline, so these names should be more natural going forward.

This wouldn't have been possible without a breaking change, but we're
already doing that.
…abernix/migrate-engine-reporting-exts-to-plugin-api
@abernix abernix modified the milestones: Release 2.13.0, Release 2.14.0 May 4, 2020
…to abernix/migrate-engine-reporting-exts-to-plugin-api
I may re-visit this consideration.
…rce`.

Leverages new life-cycle `didResolveSource` which was introduced by
[[PR #4076]] and inspired by this [[comment]].

This is much nicer!

[PR #4076]: #4076
[Comment]: https://github.com/apollographql/apollo-server/pull/3998/files#r414911049
@glasser, are you able to confirm this belief and that it should be okay?
Previously, I introduced a work-around for this in 78a4cb7,
though that is no longer necessary with the introduction of
`didResolveSource` in #4076

I'm thrilled to remove this!

Ref: #3998 (comment)
…to abernix/migrate-engine-reporting-exts-to-plugin-api
… failure.

Addresses feedback in below referenced [[Comment]].

If operation resolution (parsing and validating the document followed by
selecting the correct operation) resulted in the population of the
`operationName`, we'll use that. (For anonymous operations,
`requestContext.operationName` is null, which we represent here as the empty
string.)

If the user explicitly specified an `operationName` in their request but
operation resolution failed (due to parse or validation errors or because
there is no operation with that name in the document), we still put _that_
user-supplied `operationName` in the trace. This allows the error to be
better understood in Graph Manager. (We are considering changing the
behavior of `operationName` in these three error cases; see [[#3465]] below for
details.)

[Comment]: #3998 (comment)
[#3465]: #3465
abernix added a commit that referenced this pull request May 8, 2020
This should prove to be more ergonomic, and also allow us to attach other
useful properties to this object (for either external or internal use) in
the future.

Also, adds a test to make sure we're passing _something_!

Ref: #3998 (comment)
…to abernix/migrate-engine-reporting-exts-to-plugin-api
abernix added a commit that referenced this pull request May 8, 2020
abernix added a commit that referenced this pull request May 8, 2020
@abernix abernix requested a review from glasser May 11, 2020 12:04
…abernix/migrate-engine-reporting-exts-to-plugin-api
Copy link
Member

@glasser glasser left a comment

Choose a reason for hiding this comment

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

Other than noting the possibly unintentional possibly irrelevant change around logger this looks good to me.

@abernix abernix changed the base branch from abernix/add-schema-and-schemaHash-to-requestContext to release-2.14.0 May 12, 2020 12:06
@abernix abernix merged commit e2c8150 into release-2.14.0 May 12, 2020
@abernix
Copy link
Member Author

abernix commented May 12, 2020

@glasser Could you zoom me back into the specifics of the logger change you're referring to? Certainly seems irrelevant, but it would seem unexpected for it to have piqued your interest and should be unrelated/inadvertent unless it was a result of an out of date merge.

@glasser
Copy link
Member

glasser commented May 12, 2020

There is a logger in EngineReportingOptions that is used for a variety of things inside agent.ts. So you can theoretically override this logger to some implementation you want used for only GM-reporting stuff.

TreeBuilder also takes a logger that is used for one warning about one edge case relating to errors of the wrong type (without 'path's). Maybe even never happens? Maybe this logger was used for more in the past?

That was the only (remaining?) use of this logger within the request-specific extension.ts.

When you changed extension.ts to plugin.ts, you do this:

    requestDidStart({
      logger: requestLogger,
      schemaHash,
      metrics,
      request: { http, variables },
    }) {
      const treeBuilder: EngineReportingTreeBuilder = new EngineReportingTreeBuilder(
        {
          rewriteError: options.rewriteError,
          logger: requestLogger || logger,
        },
      );

(logger here is the logger from EngineReportingOptions)

So the effect here is that the TreeBuilder's warning now uses the request-specific logger instead of the engine-reporting-specific logger. While it generally makes sense to use the "most specific" logger for any given logging, it's not cut and dry which of those is "more specific" since one has a specific lifecycle whereas the other has a specific subsystem scope.

I think I would lean towards keeping the old behavior. ie, just ignore the logger passed to requestDidStart. But again, it only affects one probably-shouldn't-happen-much warning?

@abernix abernix deleted the abernix/migrate-engine-reporting-exts-to-plugin-api branch May 15, 2020 13:43
@abernix
Copy link
Member Author

abernix commented May 15, 2020

Thanks for the clarification, @glasser, and I missed this and didn't see de7ba72#r416714696 somehow. 🤷

I recall this now and it was a conscious decision when I recently introduced the logger in #3894. Specifically, I avoided introducing the more specific request logger to the graphql-extensions API on the premise that I would soon deprecate it.

I agree that it's less cut and dry than ideal, though the intent of the request-level logger was to capture anything that could have sandbagged a specific request, so in my mind the spirit of using the request logger here is correct, particularly since it could be linked to a specific operation in the same scoped-logger.

On the notion that it only affects the one probably-shouldn't-happen-much (I've never seen, or seen reported) warning, and additionally because we don't specify a way to override the request-level logger right now without specific assignment within a plugin, and the relative recency of this, I'm going to leave this as is for now.

If you have strong feelings about this, I'm happy to change it.

@glasser
Copy link
Member

glasser commented May 15, 2020

Nope, just wanted to make sure it was understood.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 21, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
🔌 plugins Relates to the request pipeline plugin API
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants