diff --git a/CHANGELOG.md b/CHANGELOG.md index 76bcc32a522..276fcfa3529 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,14 +6,14 @@ 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. When a release is being prepared, a new header will be (manually) created below and the the appropriate changes within that release will be moved into the new section. -- _Nothing yet!_ +- `apollo-engine-reporting`: clean up `SIGINT` and `SIGTERM` handlers when `EngineReportingAgent` is stopped; fixes 'Possible EventEmitter memory leak detected' log. [PR #3090](https://github.com/apollographql/apollo-server/pull/3090) ### v2.7.1 > [See complete versioning details.](https://github.com/apollographql/apollo-server/commit/2f87e4af9a6f1e3c8f4c51b4f77860bd3150c8c6) - `apollo-engine-reporting`: If an error is thrown by a custom variable transform function passed into the reporting option `sendVariableValues: { transform: ... }`, all variable values will be replaced with the string `[PREDICATE_FUNCTION_ERROR]`. -- `apollo-server-express: Typing fix for the `connection` property, which was missing from the `ExpressContext` interface. [PR #2959](https://github.com/apollographql/apollo-server/pull/2959) +- `apollo-server-express`: Typing fix for the `connection` property, which was missing from the `ExpressContext` interface. [PR #2959](https://github.com/apollographql/apollo-server/pull/2959) - `@apollo/gateway`: Ensure execution of correct document within multi-operation documents by including the `operationName` in the cache key used when caching query plans used in federated execution. [PR #3084](https://github.com/apollographql/apollo-server/pull/3084) ### v2.7.0 diff --git a/packages/apollo-engine-reporting/src/agent.ts b/packages/apollo-engine-reporting/src/agent.ts index 4ca18cafa26..dae6c1bdad8 100644 --- a/packages/apollo-engine-reporting/src/agent.ts +++ b/packages/apollo-engine-reporting/src/agent.ts @@ -223,6 +223,8 @@ export class EngineReportingAgent { ); private signatureCache: InMemoryLRUCache; + private signalHandlers = new Map(); + public constructor(options: EngineReportingOptions = {}) { this.options = options; this.apiKey = options.apiKey || process.env.ENGINE_API_KEY || ''; @@ -248,11 +250,15 @@ export class EngineReportingAgent { if (this.options.handleSignals !== false) { const signals: NodeJS.Signals[] = ['SIGINT', 'SIGTERM']; signals.forEach(signal => { - process.once(signal, async () => { + // Note: Node only started sending signal names to signal events with + // Node v10 so we can't use that feature here. + const handler: NodeJS.SignalsListener = async () => { this.stop(); await this.sendAllReportsAndReportErrors(); process.kill(process.pid, signal); - }); + }; + process.once(signal, handler); + this.signalHandlers.set(signal, handler); }); } @@ -430,6 +436,11 @@ export class EngineReportingAgent { // size, and stop buffering new traces. You may still manually send a last // report by calling sendReport(). public stop() { + // Clean up signal handlers so they don't accrue indefinitely. + this.signalHandlers.forEach((handler, signal) => { + process.removeListener(signal, handler); + }); + if (this.reportTimer) { clearInterval(this.reportTimer); this.reportTimer = undefined;