Skip to content

Commit

Permalink
Make ApolloServer.stop invoke ApolloGateway.stop
Browse files Browse the repository at this point in the history
Because AS is what invokes ApolloGateway.load, it should be its responsibility
to invoke the matching stop method.

apollographql/federation#452 (aimed at @apollo/gateway
0.23) will change ApolloGateway to no longer "unref" its polling timer: ie, it
makes calling `stop()` actually part of its expected API instead of something
you can ignore if you feel like it without affecting program shutdown. It has
a bit of a hack to still unref the timer if it looks like you're using an
old (pre-2.18) version of Apollo Server, but this PR (which will be released in
v2.20.0) will make ApolloServer stop the gateway for you.

Part of fixing #4428.
  • Loading branch information
glasser committed Feb 8, 2021
1 parent 0334261 commit 06e8d54
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ The version headers in this history reflect the versions of Apollo Server itself

> The changes noted within this `vNEXT` section have not been released yet. New PRs and commits which introduce changes should include an entry in this `vNEXT` section as part of their development. With few exceptions, the format of the entry should follow convention (i.e., prefix with package name, use markdown `backtick formatting` for package names and code, suffix with a link to the change-set à la `[PR #YYY](https://link/pull/YYY)`, etc.). When a release is being prepared, a new header will be (manually) created below and the appropriate changes within that release will be moved into the new section.
- `apollo-server-core`: When used with `ApolloGateway`, `ApolloServer.stop` now invokes `ApolloGateway.stop`. (This makes sense because `ApolloServer` already invokes `ApolloGateway.load` which is what starts the behavior stopped by `ApolloGateway.stop`.) Note that `@apollo/gateway` 0.23 will expect to be stopped in order for natural program shutdown to occur. [Issue #4428](https://github.com/apollographql/apollo-server/issues/4428)
- `apollo-server-core`: Avoid instrumenting schemas for the old `graphql-extensions` library unless extensions are provided. [PR #4893](https://github.com/apollographql/apollo-server/pull/4893) [Issue #4889](https://github.com/apollographql/apollo-server/issues/4889)
- `apollo-server-plugin-response-cache`: The `shouldReadFromCache` and `shouldWriteToCache` hooks were always documented as returning `ValueOrPromise<boolean>` (ie, that they could be either sync or async), but they actually only worked if they returned a bool. Now they can be either sync or async as intended. [PR #4890](http://github.com/apollographql/apollo-server/pull/4890) [Issue #4886](https://github.com/apollographql/apollo-server/issues/4886)

Expand Down
21 changes: 14 additions & 7 deletions packages/apollo-server-core/src/ApolloServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ export class ApolloServerBase {
// Store the unsubscribe handles, which are returned from
// `onSchemaChange`, for later disposal when the server stops
gateway.onSchemaChange(
schema =>
(schema) =>
(this.schemaDerivedData = Promise.resolve(
this.generateSchemaDerivedData(schema),
)),
Expand All @@ -415,17 +415,24 @@ export class ApolloServerBase {
// a federated schema!
this.requestOptions.executor = gateway.executor;

return gateway.load({ apollo: this.apolloConfig, engine: engineConfig })
.then(config => config.schema)
.catch(err => {
return gateway
.load({ apollo: this.apolloConfig, engine: engineConfig })
.then((config) => {
this.toDispose.add(
async () => gateway.stop && (await gateway.stop()),
);
return config.schema;
})
.catch((err) => {
// We intentionally do not re-throw the exact error from the gateway
// configuration as it may contain implementation details and this
// error will propagate to the client. We will, however, log the error
// for observation in the logs.
const message = "This data graph is missing a valid configuration.";
this.logger.error(message + " " + (err && err.message || err));
const message = 'This data graph is missing a valid configuration.';
this.logger.error(message + ' ' + ((err && err.message) || err));
throw new Error(
message + " More details may be available in the server logs.");
message + ' More details may be available in the server logs.',
);
});
}

Expand Down
1 change: 1 addition & 0 deletions packages/apollo-server-core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ export interface GraphQLService {
executor<TContext>(
requestContext: GraphQLRequestContextExecutionDidStart<TContext>,
): ValueOrPromise<GraphQLExecutionResult>;
stop?(): Promise<void>;
}

// This configuration is shared between all integrations and should include
Expand Down

0 comments on commit 06e8d54

Please sign in to comment.