Skip to content

fix: Ensure that file watchers are closed before Electron exits #22606

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

Merged
merged 41 commits into from
Jul 17, 2022

Conversation

astone123
Copy link
Contributor

@astone123 astone123 commented Jun 29, 2022

Closes #22026

This PR uses a will-quit hook for Electron to ensure that we close all of the DataContext file watchers before the application exits.

See the related issue for more info.

User facing changelog

  • Fixed an issue where file watchers were not completely closed prior to the Cypress app quitting, causing crashes on exit in some macOS environments.

Testing:

  • Check out develop
  • Follow the repro steps in the related issue to reproduce a SIGABORT error upon exiting the application
  • Check out this branch
  • Follow the steps again and verify that the SIGABORT error will not happen

@cypress-bot
Copy link
Contributor

cypress-bot bot commented Jun 29, 2022

Thanks for taking the time to open a PR!

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
@@ -429,7 +429,11 @@ export class DataContext {
}

async destroy () {
const destroy = util.promisify(this.coreData.servers.gqlServer?.destroy || (() => {}))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

util.promisify(() => {})

This noop didn't work because it never resolved. We replaced it with () => Promise.resolve()

@@ -170,6 +173,36 @@ export = {
makeGraphQLServer(),
])

const clearCtxAndQuit = async () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This file contains the bulk of the changes. Most of the other changes in this diff are related to awaiting function calls that are now async

@cypress
Copy link

cypress bot commented Jun 29, 2022



Test summary

37721 0 456 0Flakiness 10


Run details

Project cypress
Status Passed
Commit 0a3e614
Started Jul 17, 2022 7:17 PM
Ended Jul 17, 2022 7:33 PM
Duration 16:04 💡
OS Linux Debian - 10.11
Browser Multiple

View run in Cypress Dashboard ➡️


Flakiness

xhr.cy.js Flakiness
1 ... > logs request + response headers
2 ... > logs Method, Status, URL, and XHR
3 ... > logs request + response headers
4 ... > logs Method, Status, URL, and XHR
navigation.cy.js Flakiness
1 src/cy/commands/navigation > #visit > window immediately resolves and doesn't reload when visiting the same URL with hashes
This comment includes only the first 5 flaky tests. See all 10 flaky tests in the Cypress Dashboard.

This comment has been generated by cypress-bot as a result of this project's GitHub integration settings. You can manage this integration in this project's settings in the Cypress Dashboard

@astone123 astone123 marked this pull request as ready for review June 30, 2022 18:54
@astone123 astone123 requested review from a team as code owners June 30, 2022 18:54
@astone123 astone123 requested a review from ZachJW34 June 30, 2022 19:39

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
Copy link
Contributor

@lmiller1990 lmiller1990 left a comment

Choose a reason for hiding this comment

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

Sorry it took so long to review, I missed this one. I left a few tiny comments, once those are good let's ship it.

@@ -170,6 +173,36 @@ export = {
makeGraphQLServer(),
])

const clearCtxAndQuit = async () => {
try {
await clearCtx()
Copy link
Contributor

Choose a reason for hiding this comment

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

There is a comment saying we should not call this in runtime: https://github.com/cypress-io/cypress/pull/22606/files#diff-1827debd8088884005aba0e14a94e1e6815ceb1ad567db970f9f327d9feb7c9dR27

If we are doing this, I think we need to change the comment?

Also, maybe a comment here explaining why we clearCtx before closing? Could link to the relevant GH issue

@@ -1650,6 +1650,7 @@ module.exports = {
async run (options, loading = Promise.resolve()) {
if (require('../util/electron-app').isRunningAsElectronProcess({ debug })) {
const app = require('electron').app
const { clearCtx } = require('@packages/data-context')
Copy link
Contributor

Choose a reason for hiding this comment

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

Was there a reason to inline this require instead of putting it at the top?

Will make an eventual ESM convert easier.

Copy link
Contributor

Choose a reason for hiding this comment

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

The existing data-context require used to be at root but was changed with https://github.com/cypress-io/cypress/pull/20932/files#diff-58fd4a8e28c13b52b19c42346eade66ed1de5a8b139541dff4e94fef42c3c701R666-R667. I assume due to how the run script is getting loaded?

Regardless, I am going to revert the changes to this file for run mode. I don't think the process.exit handler is deterministic here, just like it wasn't before in the ProjectLifecycleManager. And because we don't initialize watchers in run mode, the teardown isn't necessary prior to exit.

@tbiethman
Copy link
Contributor

@astone123 @lmiller1990 I have addressed the current PR feedback and pushed a few new commits.

The biggest change was addressing the TODO regarding closing the file watchers when the ProjectConfigManager errored. I was able to keep closing these by untangling some of the circular logic between the ProjectLifecycleManager and the ProjectConfigManager. You can that see in the diff. Doing it this way allows us to keep the lifecycle manager error handling functionally equivalent while allowing for async handling within the config manager itself. I'm happy to answer more questions around that, otherwise I think we're good to go for a final review.

destroy () {
this.resetInternalState()
// @ts-ignore
process.removeListener('exit', this.onProcessExit)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we not need to remove this anymore?

Copy link
Contributor

Choose a reason for hiding this comment

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

Nope, we no longer add the listener in the first place.

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
@lmiller1990 lmiller1990 self-requested a review July 15, 2022 05:51
Copy link
Contributor

@lmiller1990 lmiller1990 left a comment

Choose a reason for hiding this comment

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

My comments are addressed. Just need CI to pass and we can merge?

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
@tbiethman tbiethman merged commit 1b68869 into develop Jul 17, 2022
@tbiethman tbiethman deleted the tbiethman/UNIFY-1816-prototype branch July 17, 2022 20:57
@cypress-bot
Copy link
Contributor

cypress-bot bot commented Jul 19, 2022

Released in 10.3.1.

This comment thread has been locked. If you are still experiencing this issue after upgrading to
Cypress v10.3.1, please open a new issue.

@cypress-bot cypress-bot bot locked as resolved and limited conversation to collaborators Jul 19, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

File watchers in DataContext are not closed consistently on process exit
4 participants