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

Release 3.6.0 #5960

Merged
merged 9 commits into from
Dec 30, 2021
Merged

Release 3.6.0 #5960

merged 9 commits into from
Dec 30, 2021

Conversation

glasser
Copy link
Member

@glasser glasser commented Dec 21, 2021

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 the main 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 into main.

glasser and others added 3 commits December 17, 2021 13:41
…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.
 - apollo-datasource-rest@3.5.0-alpha.0
 - apollo-reporting-protobuf@3.3.0-alpha.0
 - apollo-server-azure-functions@3.6.0-alpha.0
 - apollo-server-cloud-functions@3.6.0-alpha.0
 - apollo-server-cloudflare@3.6.0-alpha.0
 - apollo-server-core@3.6.0-alpha.0
 - apollo-server-express@3.6.0-alpha.0
 - apollo-server-fastify@3.6.0-alpha.0
 - apollo-server-hapi@3.6.0-alpha.0
 - apollo-server-integration-testsuite@3.6.0-alpha.0
 - apollo-server-koa@3.6.0-alpha.0
 - apollo-server-lambda@3.6.0-alpha.0
 - apollo-server-micro@3.6.0-alpha.0
 - apollo-server-plugin-base@3.5.0-alpha.0
 - apollo-server-plugin-operation-registry@3.5.0-alpha.0
 - apollo-server-plugin-response-cache@3.5.0-alpha.0
 - apollo-server-types@3.5.0-alpha.0
 - apollo-server@3.6.0-alpha.0
@glasser
Copy link
Member Author

glasser commented Dec 21, 2021

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.

glasser and others added 4 commits December 27, 2021 18:51
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.
 - apollo-datasource-rest@3.5.0-alpha.1
 - apollo-reporting-protobuf@3.3.0-alpha.1
 - apollo-server-azure-functions@3.6.0-alpha.1
 - apollo-server-cloud-functions@3.6.0-alpha.1
 - apollo-server-cloudflare@3.6.0-alpha.1
 - apollo-server-core@3.6.0-alpha.1
 - apollo-server-express@3.6.0-alpha.1
 - apollo-server-fastify@3.6.0-alpha.1
 - apollo-server-hapi@3.6.0-alpha.1
 - apollo-server-integration-testsuite@3.6.0-alpha.1
 - apollo-server-koa@3.6.0-alpha.1
 - apollo-server-lambda@3.6.0-alpha.1
 - apollo-server-micro@3.6.0-alpha.1
 - apollo-server-plugin-base@3.5.0-alpha.1
 - apollo-server-plugin-operation-registry@3.5.0-alpha.1
 - apollo-server-plugin-response-cache@3.5.0-alpha.1
 - apollo-server-types@3.5.0-alpha.1
 - apollo-server@3.6.0-alpha.1
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)
Copy link
Contributor

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"

 - apollo-datasource-rest@3.5.0
 - apollo-reporting-protobuf@3.3.0
 - apollo-server-azure-functions@3.6.0
 - apollo-server-cloud-functions@3.6.0
 - apollo-server-cloudflare@3.6.0
 - apollo-server-core@3.6.0
 - apollo-server-express@3.6.0
 - apollo-server-fastify@3.6.0
 - apollo-server-hapi@3.6.0
 - apollo-server-integration-testsuite@3.6.0
 - apollo-server-koa@3.6.0
 - apollo-server-lambda@3.6.0
 - apollo-server-micro@3.6.0
 - apollo-server-plugin-base@3.5.0
 - apollo-server-plugin-operation-registry@3.5.0
 - apollo-server-plugin-response-cache@3.5.0
 - apollo-server-types@3.5.0
 - apollo-server@3.6.0
@glasser glasser merged commit 06dd117 into main Dec 30, 2021
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 20, 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.

None yet

2 participants