Skip to content

--detectOpenHandles shouldn't report unreferenced workers. #11707

@nicolo-ribaudo

Description

@nicolo-ribaudo

🐛 Bug Report

Node.js workers have an .unref() method that, when called, makes them not prevent the main thread from exiting. It's similar to setTimeout().unref().

If a worker has been .unref()ed, Jest shouldn't report it in --detectOpenHandles. This is siilar to #8941

To Reproduce

I have two file: test.js and worker.js (I tested them in a bigger repository; if needed I'll create a self-contained repo).

test.js:

const { Worker } = require("worker_threads");

if (typeof describe === "undefined") {
  globalThis.describe = globalThis.it = (name, fn) => fn();
  globalThis.expect = () => ({
    toBe() {
      console.log("DONE");
    },
  });
}

describe("test", () => {
  it("test", () => {
    const worker = new Worker(__dirname + "/worker.js");
    worker.unref();

    expect(1).toBe(1);
  });
});

worker.js:

setInterval(() => {
  console.log("XX");
}, 1000);

Expected behavior

When running node test.js it logs "DONE", and the process exits immediately (without logging "XX").

When running test.js with Jest, it (correctly) logs

 PASS  eslint/babel-eslint-parser/test/worker.js
  test
    ✓ test (2 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.588 s, estimated 1 s

and then exits immediately.

When running test.js with Jest and --detectOpenHandles, it logs

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

  ●  WORKER

      15 | describe("test", () => {
      16 |   it("test", () => {
    > 17 |     const worker = new Worker(__dirname + "/helpers/worker.cjs");
         |                    ^
      18 |     worker.unref();
      19 |
      20 |     expect(1).toBe(1);

      at Object.<anonymous> (eslint/babel-eslint-parser/test/worker.js:17:20)
      at TestScheduler.scheduleTests (node_modules/@jest/core/build/TestScheduler.js:347:13)
      at runJest (node_modules/@jest/core/build/runJest.js:387:19)
      at _run10000 (node_modules/@jest/core/build/cli/index.js:408:7)
      at runCLI (node_modules/@jest/core/build/cli/index.js:261:3)

This worker doesn't prevent the process from exiting, so it shouldn't be reported. It should still be reported if you delete worker.unref() from my example.

envinfo

  System:
    OS: Linux 5.11 Ubuntu 21.04 (Hirsute Hippo)
    CPU: (12) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
  Binaries:
    Node: 16.3.0 - /usr/local/bin/node
    Yarn: 2.4.1-git.20210125.0f31e6910 - /usr/bin/yarn
    npm: 7.9.0 - ~/.npm-global/bin/npm
  npmPackages:
    jest: ^27.0.0 => 27.0.1 

Context

In the Babel repo we have a test where 90% of the times every test passes, but then Jest waits without ever exiting (and CircleCI kills it after 10 mins without output, marking it as failed). I tried using the --detectOpenHandles option, but it only reports a worker for which I was calling worker.unref() (CircleCI output).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions