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

experimental: Allow query plan & parsed/validated document cache config #3755

Merged
merged 3 commits into from Feb 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -9,6 +9,7 @@ The version headers in this history reflect the versions of Apollo Server itself
- Move TContext generic from requestDidStart method to ApolloServerPlugin Interface [#3525](https://github.com/apollographql/apollo-server/pull/3525)
- `apollo-server-express`: Support `CorsOptionsDelegate` type on `cors` parameter to `applyMiddleware`, to align with the supported type of the underlying [`cors`](https://npm.im/cors) middleware [itself](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/31483b781ac30f98bdf4d40a517e921f2fc2ce37/types/cors/index.d.ts#L32). [PR #3613](https://github.com/apollographql/apollo-server/pull/3613)
- `apollo-server-core`: Allow asynchronous initialization of datasources: the `initialize` method on datasources may now return a Promise, which will be settled before any resolvers are called. [#3639](https://github.com/apollographql/apollo-server/pull/3639)
- `apollo-server-core`: experimental: Allow configuration of the parsed/validated document store by introducing an `experimental_approximateDocumentStoreMiB` property to the `ApolloServer` constructor options which overrides the default cache size of 30MiB. [#3755](https://github.com/apollographql/apollo-server/pull/3755)

### v2.9.16

Expand Down
12 changes: 12 additions & 0 deletions docs/source/api/apollo-gateway.mdx
Expand Up @@ -91,6 +91,18 @@ example of using `ApolloGateway`, see [Implementing a federated graph](/federati
If `true`, the gateway logs startup messages, along with the query plan for
each incoming request. The default value is `false`.

* `experimental_approximateQueryPlanStoreMiB`: `number`

> **This property is experimental.** It may be removed or change at any time, even within a patch release.

When set, this sets the approximate size of the query plan store (in MiB).
This cache is used to save query plans for re-use on subsequent queries
which resolve to the same `queryHash` (a SHA-256 of incoming operation).

When this property is omitted, the cache is still enabled with a default
size of 30MiB, which is generally sufficient unless the server is
processing a high number of unique operations.

#### Returns

An `ApolloGateway` instance, which you then pass as the `gateway` configuration option to the `ApolloServer` constructor, like so:
Expand Down
13 changes: 13 additions & 0 deletions docs/source/api/apollo-server.md
Expand Up @@ -144,6 +144,19 @@ new ApolloServer({

Pass the integration-specific CORS options. `false` removes the CORS middleware and `true` uses the defaults. This option is only available to `apollo-server`. For other server integrations, place `cors` inside of `applyMiddleware`.

* `experimental_approximateDocumentStoreSizeMiB`: `number`

> **This property is experimental.** It may be removed or change at any time, even within a patch release.

When set, this sets the approximate size of the parsed/validated document
store (in MiB). This cache is used to save the already parsed and validated
`DocumentNode`s for re-use on subsequent queries which resolve to the same
`queryHash` (a SHA-256 of incoming operation).

When this property is omitted, the cache is still enabled with a default
size of 30MiB, which is generally sufficient unless the server is processing
a high number of unique operations.

#### Returns

`ApolloServer`
Expand Down
1 change: 1 addition & 0 deletions packages/apollo-gateway/CHANGELOG.md
Expand Up @@ -7,6 +7,7 @@
* Reduce interface expansion for types contained to a single service [#3582](https://github.com/apollographql/apollo-server/pull/3582)
* Instantiate one `CachedFetcher` per gateway instance. This resolves a condition where multiple federated gateways would utilize the same cache store could result in an `Expected undefined to be a GraphQLSchema` error. [#3704](https://github.com/apollographql/apollo-server/pull/3704)
* Gateway: minimize downstream request size [#3737](https://github.com/apollographql/apollo-server/pull/3737)
* experimental: Allow configuration of the query plan store by introducing an `experimental_approximateQueryPlanStoreMiB` property to the `ApolloGateway` constructor options which overrides the default cache size of 30MiB. [#3755](https://github.com/apollographql/apollo-server/pull/3755)

# v0.11.6

Expand Down
10 changes: 9 additions & 1 deletion packages/apollo-gateway/src/index.ts
Expand Up @@ -58,6 +58,7 @@ interface GatewayConfigBase {
experimental_updateServiceDefinitions?: Experimental_UpdateServiceDefinitions;
experimental_didUpdateComposition?: Experimental_DidUpdateCompositionCallback;
experimental_pollInterval?: number;
experimental_approximateQueryPlanStoreMiB?: number;
}

interface RemoteGatewayConfig extends GatewayConfigBase {
Expand Down Expand Up @@ -178,6 +179,8 @@ export class ApolloGateway implements GraphQLService {
// how often service defs should be loaded/updated (in ms)
protected experimental_pollInterval?: number;

private experimental_approximateQueryPlanStoreMiB?: number;

constructor(config?: GatewayConfig) {
this.config = {
// TODO: expose the query plan in a more flexible JSON format in the future
Expand Down Expand Up @@ -219,6 +222,9 @@ export class ApolloGateway implements GraphQLService {
this.experimental_didUpdateComposition =
config.experimental_didUpdateComposition;

this.experimental_approximateQueryPlanStoreMiB =
config.experimental_approximateQueryPlanStoreMiB;

if (
isManagedConfig(config) &&
config.experimental_pollInterval &&
Expand Down Expand Up @@ -609,7 +615,9 @@ export class ApolloGateway implements GraphQLService {
// only using JSON.stringify on the DocumentNode (and thus doesn't account
// for unicode characters, etc.), but it should do a reasonable job at
// providing a caching document store for most operations.
maxSize: Math.pow(2, 20) * 30,
maxSize:
Math.pow(2, 20) *
(this.experimental_approximateQueryPlanStoreMiB || 30),
sizeCalculator: approximateObjectSize,
});
}
Expand Down
7 changes: 6 additions & 1 deletion packages/apollo-server-core/src/ApolloServer.ts
Expand Up @@ -153,6 +153,8 @@ export class ApolloServerBase {
/** @deprecated: This is undefined for servers operating as gateways, and will be removed in a future release **/
protected schema?: GraphQLSchema;
private toDispose = new Set<() => void>();
private experimental_approximateDocumentStoreMiB:
Config['experimental_approximateDocumentStoreMiB'];

// The constructor should be universal across all environments. All environment specific behavior should be set by adding or overriding methods
constructor(config: Config) {
Expand All @@ -176,6 +178,7 @@ export class ApolloServerBase {
playground,
plugins,
gateway,
experimental_approximateDocumentStoreMiB,
...requestOptions
} = config;

Expand Down Expand Up @@ -716,7 +719,9 @@ export class ApolloServerBase {
// only using JSON.stringify on the DocumentNode (and thus doesn't account
// for unicode characters, etc.), but it should do a reasonable job at
// providing a caching document store for most operations.
maxSize: Math.pow(2, 20) * 30,
maxSize:
Math.pow(2, 20) *
(this.experimental_approximateDocumentStoreMiB || 30),
sizeCalculator: approximateObjectSize,
});
}
Expand Down
1 change: 1 addition & 0 deletions packages/apollo-server-core/src/types.ts
Expand Up @@ -112,6 +112,7 @@ export interface Config extends BaseConfig {
uploads?: boolean | FileUploadOptions;
playground?: PlaygroundConfig;
gateway?: GraphQLService;
experimental_approximateDocumentStoreMiB?: number;
}

export interface FileUploadOptions {
Expand Down