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

Open handlers in Jest #10

Open
isTravis opened this issue Sep 5, 2019 · 4 comments
Open

Open handlers in Jest #10

isTravis opened this issue Sep 5, 2019 · 4 comments

Comments

@isTravis
Copy link

isTravis commented Sep 5, 2019

I'm using citation-js which in turn uses sync-request which in turn uses sync-rpc. Simply importing the package causes my CI build to fail as Jest doesn't exit and throws the following warning:

Screen Shot 2019-09-05 at 1 50 28 PM

This happens when running jest 24.5.0 on node 10.14.1.

@ondrejrohon
Copy link

I had similar issue, this was preventing nodemon correct restart, it left node process hanging and therefore nodemon was complaining that port is in use. Removing sync-rpc solved it.

@ForbesLindesay
Copy link
Owner

We call unref, so I think this is a bug in jest/nodemon. We could add a method for explicitly terminating the child process, but other than that there's not much we can do as the child process is required for sync-rpc to function

p.unref();

@da70
Copy link

da70 commented Oct 22, 2020

I'm having the same problem(s):

Reproduction:

/tmp/sync-rpc_issue-10> ls
example.test.js		example2.test.js	node_modules		package.json		yarn.lock
/tmp/sync-rpc_issue-10> alias jest
alias jest='node_modules/.bin/jest'
/tmp/sync-rpc_issue-10> cat package.json 
{
  "dependencies": {
    "jest": "^26.6.0",
    "sync-request": "^6.1.0"
  }
}
/tmp/sync-rpc_issue-10> cat example.test.js 
"use strict";

const request = require( 'sync-request' );

describe( 'describe', () => {
    it( 'test', () => {
        expect( true ).toBeTruthy();
    } );
} );
/tmp/sync-rpc_issue-10> diff example.test.js example2.test.js 
/tmp/sync-rpc_issue-10> ps | grep 'sync-rpc/lib/worker.js' | grep -v grep
/tmp/sync-rpc_issue-10> jest example.test.js 
 PASS  ./example.test.js
  describe
    ✓ test (3 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.731 s, estimated 2 s
Ran all test suites matching /example.test.js/i.
/tmp/sync-rpc_issue-10> ps | grep 'sync-rpc/lib/worker.js' | grep -v grep
 6331 ttys001    0:00.14 /Users/da70/.nvm/versions/node/v14.10.1/bin/node /private/tmp/sync-rpc_issue-10/node_modules/sync-rpc/lib/worker.js 58547
/tmp/sync-rpc_issue-10> jest example.test.js example2.test.js 
 PASS  ./example2.test.js
 PASS  ./example.test.js

Test Suites: 2 passed, 2 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        2.784 s
Ran all test suites matching /example.test.js|example2.test.js/i.
Jest did not exit one second after the test run has completed.

This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.
^C
/tmp/sync-rpc_issue-10> ps | grep 'sync-rpc/lib/worker.js' | grep -v grep
 6331 ttys001    0:00.18 /Users/da70/.nvm/versions/node/v14.10.1/bin/node /private/tmp/sync-rpc_issue-10/node_modules/sync-rpc/lib/worker.js 58547
/tmp/sync-rpc_issue-10> jest --detectOpenHandles example.test.js 
 PASS  ./example.test.js
  describe
    ✓ test (6 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        6.508 s
Ran all test suites matching /example.test.js/i.

Jest has detected the following 1 open handle potentially keeping Jest from exiting:

  ●  PROCESSWRAP

      at start (node_modules/sync-rpc/lib/index.js:33:13)
      at sendMessage (node_modules/sync-rpc/lib/index.js:133:17)
      at createClient (node_modules/sync-rpc/lib/index.js:173:27)
      at Object.<anonymous> (node_modules/sync-request/lib/index.js:16:14)

/tmp/sync-rpc_issue-10> ps | grep 'sync-rpc/lib/worker.js' | grep -v grep
 6331 ttys001    0:00.18 /Users/da70/.nvm/versions/node/v14.10.1/bin/node /private/tmp/sync-rpc_issue-10/node_modules/sync-rpc/lib/worker.js 58547
 6413 ttys001    0:00.16 /Users/da70/.nvm/versions/node/v14.10.1/bin/node /private/tmp/sync-rpc_issue-10/node_modules/sync-rpc/lib/worker.js 58591
/tmp/sync-rpc_issue-10> 

Summary of above:

  • Simple require of sync-request is enough to cause issues in Jest.
  • If the Jest process runs to the end, the sync-rpc/lib/worker.js process is not terminated. At one point I discovered I had 314 orphan sync-rpc worker processes running as the result of repeated execution of jest tests in Intellij and on the command line.
  • If Jest is run with --detectOpenHandles, there will be a throw error/warning about an open handle.
  • Running Jest with more than one test file causes Jest to hang at the end, requiring a Ctrl-C to terminate. After the Jest process is killed, there are no orphan processes (in examples above the orphan process seen after the Ctrl-C is the one from the single test file run before). Re-running Jest against the same multiple test files using --detectOpenHandles allows Jest to run to completion, but with the result of the open handle warning/error plus orphan processes (unlike when Jest is killed using Ctrl-C).

@ForbesLindesay: could you try adding the explicit termination of the child process that you mention in the previous comment? I notice that currently the child process is killed under certain conditions:

  process.on('exit', () => {
    p.kill();
  });

...but while this seems to take care of the orphaned process in the event of a Ctrl-C sending a signal, it is not sufficient to prevent the general problem when running in Jest. I've not looked into the Jest code so can't say where the root cause lies, but I imagine this bug might surface in other contexts other than Jest.

I replaced sync-request with sync-fetch and the problem of open handles and orphan node processes went away. I found sync-fetch through @isTravis's ticket in larsgw/citation.js Jest builds unable to exit #190.
I would like to stay with sync-request though, if possible, though.

@zyf0330
Copy link

zyf0330 commented Aug 2, 2022

We call unref, so I think this is a bug in jest/nodemon. We could add a method for explicitly terminating the child process, but other than that there's not much we can do as the child process is required for sync-rpc to function

p.unref();

subprocess.unref() doesn't mean that. This method lets subprocess not to prevent parent process exiting. So after parent exits, sub process(sync-rpc) becomes orphan process.
So the right way is like @da70 said, let sub process exit when parent process exit, not to call subprocess.unref().

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

No branches or pull requests

5 participants