Skip to content

Commit

Permalink
Cleanup dangling chromium processes on exit. Resolves #394
Browse files Browse the repository at this point in the history
  • Loading branch information
claabs committed Jun 16, 2024
1 parent afcf312 commit cae1c4e
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 18 deletions.
28 changes: 14 additions & 14 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"entrypoint-config": "node dist/src/entrypoint-config.js",
"build": "rimraf dist && tsc",
"lint": "tsc --noEmit && eslint .",
"docker:build": "docker build . -t charlocharlie/epicgames-freegames-node:latest --target deploy",
"docker:build": "docker build . -t charlocharlie/epicgames-freegames-node:latest --target deploy --build-arg=\"COMMIT_SHA=$(git rev-parse HEAD)\"",
"docker:build-debian": "docker build . -t charlocharlie/epicgames-freegames-node:debian --target deploy --file Dockerfile.debian",
"docker:build-dev": "docker build . -t charlocharlie/epicgames-freegames:dev --target deploy",
"docker:run": "docker run --rm -ti -v $(pwd)/config:/usr/app/config -p 3000:3000 -p 3001:3001 -e DEBUG=puppeteer-extra-plugin:portal* charlocharlie/epicgames-freegames-node:latest",
Expand Down
17 changes: 16 additions & 1 deletion src/common/puppeteer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import pidtree from 'pidtree';
import findProcess from 'find-process';
import { ETCCookie, ToughCookieFileStore } from './cookie.js';
import { config } from './config/index.js';
import { getCommitSha } from '../version.js';

const puppeteer = _puppeteer as unknown as PuppeteerExtra;
const stealth = StealthPlugin();
Expand Down Expand Up @@ -154,7 +155,7 @@ const retryFunction = async <T>(
chromiumProcesses.forEach((p) => process.kill(p.pid));
if (attempts >= MAX_ATTEMPTS) {
L.error(
`If not already, consider using the Debian (:bullseye-slim) version of the image. More: https://github.com/claabs/epicgames-freegames-node#docker-configuration`,
`If not already, consider using the Debian (:debian) version of the image. More: https://github.com/claabs/epicgames-freegames-node#docker-configuration`,
);
throw new Error(`Could not do ${outputName} after ${MAX_ATTEMPTS + 1} failed attempts.`);
}
Expand All @@ -166,6 +167,20 @@ const retryFunction = async <T>(
}
};

export const killBrowserProcesses = async (L: Logger) => {
if (!getCommitSha()) return; // Don't kill processes if not in docker
const afterProcesses = await pidtree(process.pid);
const newProcesses = await Promise.all(
afterProcesses.map(async (p) => (await findProcess('pid', p))[0]),
);
const browserProcesses = newProcesses.filter(
(p): p is NonNullable<typeof p> =>
p !== undefined && ['chromium', 'chrome', 'headless_shell'].some((n) => p.name.includes(n)),
);
L.debug({ browserProcesses }, 'Killing dangling browser processes');
browserProcesses.forEach((p) => process.kill(p.pid));
};

/**
* Create a new page within a wrapper that will retry if it hangs for 30 seconds
*/
Expand Down
6 changes: 4 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import logger from './common/logger.js';
import { sendNotification, testNotifiers } from './notify.js';
import { checkForUpdate, logVersionOnError } from './version.js';
import PuppetLogin from './puppet/login.js';
import { safeLaunchBrowser } from './common/puppeteer.js';
import { killBrowserProcesses, safeLaunchBrowser } from './common/puppeteer.js';
import PuppetFreeGames from './puppet/free-games.js';
import { createServer } from './common/server.js';
import { convertImportCookies } from './common/cookie.js';
Expand Down Expand Up @@ -84,13 +84,15 @@ export async function main(): Promise<void> {
);
await Promise.all(accountPromises);
server.close();
await killBrowserProcesses(logger);
logger.info('Exiting successfully');
exit(0); // For some reason, puppeteer will keep a zombie promise alive and stop Node from exiting
}
}

main().catch((err) => {
main().catch(async (err) => {
logger.error(err);
await killBrowserProcesses(logger);
logVersionOnError();
exit(1);
});
4 changes: 4 additions & 0 deletions src/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ export async function checkForUpdate(): Promise<void> {
}
}

export const getCommitSha = () => {
return COMMIT_SHA;
};

export function logVersionOnError(): void {
if (COMMIT_SHA || BRANCH || DISTRO) {
L.warn({ COMMIT_SHA, BRANCH, DISTRO }, 'Current version');
Expand Down

0 comments on commit cae1c4e

Please sign in to comment.