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

Fix childprocess killing when the parent process SIGINTs #6011

Merged
merged 8 commits into from Jun 15, 2020

Conversation

TimvdLippe
Copy link
Contributor

@TimvdLippe TimvdLippe commented Jun 12, 2020

If you ctrl + c the Puppeteer parent process, we would sometimes
not properly handle killing of the child processes. This would then
leave child processes behind, with running Chromium instances. This
in turn could block Puppeteer from launching again and results in
cryptic errors.

Instead of using the generic process.kill with the process id
(which for some reason is negative the pid, which I don't get),
we can kill the child process directly by calling proc.kill.

Additionally, we have to remove the eventlisteners as the last
invocation of a Node emitter callback. If we remove the listener
before the full callback is run, it would prevent further execution.
E.g. if the first call is the removal of the event listener, then the
cleanup later in the callback would not happen.

You can test this locally by running the unittests (npm run unit)
and terminating the process prematurely (ctrl + c). Before this
change, the process would terminate with exit code 0. With this
change, it now properly terminates with exit code 130 (as defined
by the BrowserRunner.ts in the SIGINT callback).

Lastly, I added a more helpful error message in the event that
Puppeteer is not able to clean up the Node process. In theory,
this should now no longer happen. However, if it does, we now
explain what is going on and where users can report their bug.

After this change, whenever you run the unit tests or anything
related to Puppeteer, you should have zero browser processes
lingering. E.g. ps aux | grep Chromium should show no
results. This therefore prevents the need for continuous killing
of the browser processes when working on Puppeteer.

Fixes #5729
Fixes #4796
Fixes #4963
Fixes #4333
Fixes #1825

If you `ctrl + c` the Puppeteer parent process, we would sometimes
not properly handle killing of the child processes. This would then
leave child processes behind, with running Chromium instances. This
in turn could block Puppeteer from launching again and results in
cryptic errors.

Instead of using the generic `process.kill` with the process id
(which for some reason is negative the pid, which I don't get),
we can kill the child process directly by calling `proc.kill`.
@TimvdLippe
Copy link
Contributor Author

This is an attempt to fix the pesky "ctrl + C and now my Puppeteer is broken" issue. Pushing this to Travis to see if it is happy. I will need to do more testing locally verify it is actually fixed. Would be great if you could test this too!

@TimvdLippe
Copy link
Contributor Author

Seems like there is only 1 test failing. That seems hopeful. There are some failures on Windows though. But I suppose we can use the same proc.kill there.

@jackfranklin
Copy link
Collaborator

The test failures look like a simple error message has changed too which is great.

Could we write a test that demonstrates this new behaviour?

@TimvdLippe TimvdLippe marked this pull request as ready for review June 15, 2020 11:21
On Windows, it might not always cleanup the process, as it was
already cleaned up. We can relax the check here.
@@ -1,4 +1,6 @@
module.exports = {
reporter: 'dot',
// Allow `console.logs` to show up during test execution
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
// Allow `console.logs` to show up during test execution
// Allow `console.log`s to show up during test execution

Comment on lines 156 to 157
throw new Error(`${PROCESS_ERROR_EXPLANATION}
Error cause: ${error.stack}`);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit to maintain indentation:

Suggested change
throw new Error(`${PROCESS_ERROR_EXPLANATION}
Error cause: ${error.stack}`);
throw new Error(`${PROCESS_ERROR_EXPLANATION}\nError cause: ${error.stack}`);

Copy link
Member

@mathiasbynens mathiasbynens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks for looking into this 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
4 participants