Merge pull request #33030 from backstage/sennyeya/mem-leak
fix(openapi-jest-utils): memory leak in proxy clean up
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/backend-openapi-utils': patch
|
||||
---
|
||||
|
||||
Fixes a memory leak during `wrapServer` where stopped servers weren't removed from the clean up list.
|
||||
@@ -58,14 +58,40 @@ export class Proxy {
|
||||
this.express.server = server;
|
||||
}
|
||||
|
||||
stop() {
|
||||
async stop() {
|
||||
if (Object.keys(this.#openRequests).length > 0) {
|
||||
throw new Error('There are still open requests');
|
||||
}
|
||||
this.server.stop();
|
||||
if (!this.express.server) {
|
||||
throw new Error(
|
||||
'Proxy server was not initialized with an express server',
|
||||
);
|
||||
}
|
||||
const results = await Promise.allSettled([
|
||||
this.server.stop(),
|
||||
|
||||
// If this isn't expressly closed, it will cause a jest memory leak warning.
|
||||
this.express.server?.close();
|
||||
// If this isn't expressly closed, it will cause a jest memory leak warning.
|
||||
new Promise((resolve, reject) => {
|
||||
this.express.server?.close(err => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(undefined);
|
||||
}
|
||||
});
|
||||
}),
|
||||
]);
|
||||
if (results.some(result => result.status === 'rejected')) {
|
||||
const errors = results
|
||||
.filter(
|
||||
(result): result is PromiseRejectedResult =>
|
||||
result.status === 'rejected',
|
||||
)
|
||||
.map(result => result.reason);
|
||||
throw new Error(
|
||||
`Failed to stop proxy server: ${errors.map(e => e.message).join(', ')}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
get url() {
|
||||
|
||||
@@ -17,7 +17,7 @@ import { Express } from 'express';
|
||||
import { Server } from 'node:http';
|
||||
import { Proxy } from './proxy/setup';
|
||||
|
||||
const proxiesToCleanup: Proxy[] = [];
|
||||
const proxiesToCleanup: Set<Proxy> = new Set();
|
||||
|
||||
/**
|
||||
* !!! THIS CURRENTLY ONLY SUPPORTS SUPERTEST !!!
|
||||
@@ -29,7 +29,7 @@ const proxiesToCleanup: Proxy[] = [];
|
||||
*/
|
||||
export async function wrapServer(app: Express): Promise<Server> {
|
||||
const proxy = new Proxy();
|
||||
proxiesToCleanup.push(proxy);
|
||||
proxiesToCleanup.add(proxy);
|
||||
await proxy.setup();
|
||||
|
||||
const server = app.listen(proxy.forwardTo.port);
|
||||
@@ -48,10 +48,12 @@ function registerHooks() {
|
||||
}
|
||||
registered = true;
|
||||
|
||||
afterAll(() => {
|
||||
for (const proxy of proxiesToCleanup) {
|
||||
proxy.stop();
|
||||
}
|
||||
afterAll(async () => {
|
||||
const stopPromises = Array.from(proxiesToCleanup).map(proxy =>
|
||||
proxy.stop(),
|
||||
);
|
||||
await Promise.allSettled(stopPromises);
|
||||
proxiesToCleanup.clear();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user