-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Release 3.6.0 #5960
Release 3.6.0 #5960
Conversation
…lds (#5956) In Apollo Studio, the "Fields" page lets you see how often your fields are *executed* by operations --- ie, how often their resolvers run. It additionally lets you see which clients and operations ran those operations. However, knowing if an operation *executed* a field doesn't tell the whole story about the relationship between operations and fields. You might also be curious to learn if a field was textually referenced in the operation itself. It's possible for a field to be referenced without executing. In fact, there are many reasons this can happen: - The field is nested under another field which evaluates to null - The field is nested under another field which evaluates to an empty list - The field is nested under a non-matching fragment - The field is nested under `@include` or `@skip` If you're using the Fields page to determine "what are all the operations that use this field", you probably want to know about these usages too! It's also possible for a field to be executed without being referenced. That's because when we track "executed fields", we are always tracking the concrete object type that is being executed, not an interface type it may have been resolved through. So with schema: ```graphql interface Animal { legs: Int } type Dog implements Animal { legs: Int } type Query { myFavoriteAnimal: Animal # In practice, always returns a Dog } ``` the operation `{ myFavoriteAnimal { legs } }` "references" `Animal.legs`, not `Dog.legs`, but it is the field `Dog.legs` that is executed. (Additionally, when using federation, fields can be executed without being referenced in the operation if the query plan requires them to be executed to fulfill an `@requires` or `@key` directive.) This PR extends Apollo Server's usage reporting plugin to provide a list of "referenced fields" along with every operation. Note that these fields depend only on the operation, not on the variables passed or anything at execution time, so we don't need one set per trace, just one set per operation. In addition to the fact that this statistic is an interesting one, this will also mean that the Fields page can be useful without needing full execution tracing. There is a real performance impact of full execution tracing, especially in the federation context where the ftv1 protocol involves sending subgraph traces to the gateway/router in-band in the response. And not every GraphQL server supports full execution tracing in the first place. With support for referenced fields on the Fields page, you will be able to run a gateway/router in front of an arbitrary subgraph without federated tracing (whether you want to do this for performance or lack of implementation reasons) and still get some useful data on the Fields page. (You can then perhaps run full tracing on a sampled subset of queries to get reasonable approximate execution data too.) Note that the new Studio functionality may not be in general availability when this PR merges into the Apollo Server release branch or when the first alphas are created; it will be fully enabled (including docs) by the time this PR is released in a non-prerelease. As part of the implementation, we extend the existing "signature cache" to cache the referenced field list as well. Note that the signature is a pure function of the operation, whereas the referenced field list also depends on the schema, so we add a little mechanism to throw out the cache if the schema changes. Fixes #5708.
- [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected]
The main feature of this release is an improvement to Studio usage reporting to allow for field usage to be reported without full execution traces. There's still a little bit more documentation work to do on the Studio side before this can be released. #5956 is the main PR which has merged into this branch. I have released an alpha but there's not much need to start testing this release until the enabled feature is ready end to end. I expect that to be before the end of the year; if not I'll cut a new 3.5 release with the other changes. |
The usage reporting plugin already has an `includeRequest` option which allows you to tell the plugin to completely ignore an operation. One reason you may have wanted to use this is to avoid the overhead of capturing a full field-by-field execution trace. But in this case, `includeRequest: false` is overkill: it removes the operation from aspects of Studio such as the Operations page and schema checks which don't require full execution traces to operate. This PR adds a new option, `fieldLevelInstrumentation`, which is invoked after includeRequest returns true. If you return false from this operation, you won't incur the overhead of capturing a detailed trace (either directly in this process, or in subgraphs if this process is a Gateway). Most of Studio's features (including the newly-added "referencing operations" column on the Fields page) will still reflect the existence of this operation. As of the end of 2021, the features that this operation will not contribute to are: - The "field executions" column on the Fields page - The per-field timing hints shown in Explorer and in vscode-graphql - The trace view on the Operations page Apollo Server now sends both an "observed execution count" and "estimated execution count" for each field (for each operation and client). The former is literally how many times we saw the field get executed (only during operations where `fieldLevelInstrumentation` returned truthy). If the hook only returns true or false, the latter is the same, but you may also return a number (typically either 0 or at least 1) which represents a weight for that operation; the "estimated execution count" will be incremented by that number instead of by 1. So for example, with: fieldLevelInstrumentation: () => Math.random() < 0.01 ? 1/0.01 : false Apollo Server will instrument 1% of operations, and the "estimated execution count" will be 100 times more than the observed execution count. (You can imagine more sophisticated implementations of `fieldLevelInstrumentation` which sample more common operations more aggressively than rare operations.) If you pass a number for `fieldLevelInstrumentation`, it is equivalent to passing a function of the form in the above example; that is, the previous example behaves identically to `fieldLevelInstrumentation: 0.01`. The `latency_count` sent with field stats (which powers per-field timing hints) is now always scaled by the given fact (ie, there's no separate "observed histogram"). Note that the semantics of the `requestContext.metrics.captureTraces` field changes with this PR. Previously its value matched the value returned by the `includeRequest` hook; now it matches the truthiness of the value returned by the `fieldLevelInstrumentation` hook. This field determines whether Apollo Gateway includes the `apollo-federation-include-trace` header with outgoing requests so this is an appropriate change. Since this may provide a common use case for running a GraphQL server without any need for per-field instrumentation, the request pipeline now only instruments the schema if it ever sees a willResolveField callback. This *almost* means that if you're running a monolithic server with fieldLevelInstrumentation always returning false (or usage reporting disabled), or if you're running a subgraph whose gateway has fieldLevelInstrumentation:false (and thus never receives a request with the `apollo-federation-include-trace` header), then execution won't have the small performance impact of instrumentation. In practice you need to also disable the cache control plugin to get this speedup, as it is installed by default and uses willResolveField to implement dynamic cache control. If this optimization proves to be important we can provide a mode of the cache control plugin that doesn't allow for dynamic cache control. (Alternatively we may eventually find a way to support the instrumentation of GraphQL execution with lower overhead.) Part of #5708.
- [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected]
This is currently a dead link but will be fixed before 3.6 is released.
CHANGELOG.md
Outdated
|
||
- `apollo-server-core`: Studio usage reporting now reports "referenced operations" for fields in addition to "field executions", which can be seen on the Studio Fields page. This new statistic covers uses of fields that are not executed. It is also more efficient to generate and (for Apollo Gateways) does not require subgraphs to support federated tracing. Additionally, the new `fieldLevelInstrumentation` option to `ApolloServerPluginUsageReporting` allows you to disable field-level tracing on a per-operation basis and to report weights for operations to allow for estimates of the field execution count even when not all operations are instrumented. Note that the semantics of the `requestContext.metrics.captureTraces` field have changed. See the [Studio Fields page docs](https://www.apollographql.com/docs/studio/metrics/field-usage/) and the [`fieldLevelInstrumentation` docs](https://www.apollographql.com/docs/apollo-server/api/plugin/usage-reporting/#fieldlevelinstrumentation) for more details. [Issue #5708](https://github.com/apollographql/apollo-server/issues/5708) [PR #5956](https://github.com/apollographql/apollo-server/pull/5956) [PR #5963](https://github.com/apollographql/apollo-server/pull/5963) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"covers" -> "provides visibility into"
comma after "per-operation basis"
- [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected] - [email protected]
As with release PRs in the past, this is a PR tracking a
release-x.y.z
branch for an upcoming release of Apollo Server. 🙌 The version in the title of this PR should correspond to the appropriate branch.Check the appropriate milestone (to the right) for more details on what we hope to get into this release!
The intention of these release branches is to gather changes which are intended to land in a specific version (again, indicated by the subject of this PR). Release branches allow additional clarity into what is being staged, provide a forum for comments from the community pertaining to the release's stability, and to facilitate the creation of pre-releases (e.g.
alpha
,beta
,rc
) without affecting themain
branch.PRs for new features might be opened against or re-targeted to this branch by the project maintainers. The
main
branch may be periodically merged into this branch up until the point in time that this branch is being prepared for release. Depending on the size of the release, this may be once it reaches RC (release candidate) stage with an-rc.x
release suffix. Some less substantial releases may be short-lived and may never have pre-release versions.When this version is officially released onto the
latest
npm tag, this PR will be merged intomain
.