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

Prisma client does not clean up itself after test #13575

Closed
ogroppo opened this issue May 31, 2022 · 5 comments
Closed

Prisma client does not clean up itself after test #13575

ogroppo opened this issue May 31, 2022 · 5 comments
Assignees
Labels
bug/0-unknown Bug is new, does not have information for reproduction or reproduction could not be confirmed. kind/bug A reported bug. team/client Issue for team Client. topic: jest topic: memory leak topic: performance/memory

Comments

@ogroppo
Copy link

ogroppo commented May 31, 2022

Bug description

It has been noticed that using prisma client in integration tests (jest), leads to memory usage building up and never being released (--logHeapUsage)

the $disconnect method seems not to have the desired effect, still the error is

 FAIL  tests/memory.test.ts
  ● Test suite failed to run

    EXPERIMENTAL FEATURE!
    Your test suite is leaking memory. Please ensure all references are cleaned.

    There is a number of things that can leak memory:
      - Async operations that have not finished (e.g. fs.readFile).
      - Timers not properly mocked (e.g. setInterval, setTimeout).
      - Keeping references to the global scope.

      at onResult (node_modules/.pnpm/@jest+core@28.1.0/node_modules/@jest/core/build/TestScheduler.js:188:18)
      at node_modules/.pnpm/@jest+core@28.1.0/node_modules/@jest/core/build/TestScheduler.js:300:17
      at node_modules/.pnpm/emittery@0.10.2/node_modules/emittery/index.js:311:13
          at Array.map (<anonymous>)
      at Emittery.emit (node_modules/.pnpm/emittery@0.10.2/node_modules/emittery/index.js:309:23)

Similar issues
#12153
#8989

How to reproduce

minimal repo:
https://github.com/codeledge/prisma-memory-leak-repro

Just pnpm i && pnpm t it runs a simple test with jest and the --detectLeaks flag

Expected behavior

the client should be destroyed and leave no traces after test process finishes

Prisma information

https://github.com/codeledge/prisma-memory-leak-repro

Environment & setup

  • OS: OSX
  • Database: Postgres
  • Node.js version: 16

Prisma Version

prisma : 3.14.0
@prisma/client : 3.14.0
Current platform : darwin

@ogroppo ogroppo added the kind/bug A reported bug. label May 31, 2022
@jkomyno jkomyno added team/client Issue for team Client. topic: memory leak bug/0-unknown Bug is new, does not have information for reproduction or reproduction could not be confirmed. bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. and removed bug/0-unknown Bug is new, does not have information for reproduction or reproduction could not be confirmed. labels May 31, 2022
@garrensmith
Copy link
Contributor

Thanks for reporting this. We are aware of the issue. I'm closing this issue. You can follow along #12339

@janpio
Copy link
Member

janpio commented Sep 2, 2023

Reopening as it has its own reproduction that hopefully will help us understand the issue properly.

@janpio janpio reopened this Sep 2, 2023
@Jolg42 Jolg42 self-assigned this Nov 2, 2023
@Jolg42
Copy link
Member

Jolg42 commented Nov 2, 2023

I tried https://github.com/codeledge/prisma-memory-leak-repro as is on Node.js v20.8.1
And I could reproduce the same output.
But, I did not succeed in having it passing without Prisma

I replaced the contents of memory.test.ts by the following

describe("schema", () => {
  test("something", async () => {
  });
});

And then ran pnpm t which told me there was a memory leak

> jest --detectLeaks

ts-jest[config] (WARN) message TS151001: If you have issues related to imports, you should consider setting `esModuleInterop` to `true` in your TypeScript configuration file (usually `tsconfig.json`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information.
 FAIL  tests/memory.test.ts
  ● Test suite failed to run

    EXPERIMENTAL FEATURE!
    Your test suite is leaking memory. Please ensure all references are cleaned.

    There is a number of things that can leak memory:
      - Async operations that have not finished (e.g. fs.readFile).
      - Timers not properly mocked (e.g. setInterval, setTimeout).
      - Keeping references to the global scope.

      at onResult (node_modules/.pnpm/@jest+core@28.1.0/node_modules/@jest/core/build/TestScheduler.js:188:18)
      at node_modules/.pnpm/@jest+core@28.1.0/node_modules/@jest/core/build/TestScheduler.js:300:17
      at node_modules/.pnpm/emittery@0.10.2/node_modules/emittery/index.js:311:13
          at Array.map (<anonymous>)
      at Emittery.emit (node_modules/.pnpm/emittery@0.10.2/node_modules/emittery/index.js:309:23)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        2.365 s
Ran all test suites.
Segmentation fault (core dumped)
 ELIFECYCLE  Test failed. See above for more details.

I tried upgrading the dependencies with npx npm-check-updates -u
But I got the same result.
From this point, all dependencies were updated, and Prisma version is now 5.5.2
See Jolg42/prisma-memory-leak-repro#1

I now switched to Node.js v18.18.2 and finally got a passing test when empty

> jest --detectLeaks

ts-jest[config] (WARN) message TS151001: If you have issues related to imports, you should consider setting `esModuleInterop` to `true` in your TypeScript configuration file (usually `tsconfig.json`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information.
 PASS  tests/memory.test.ts
  schema
    ✓ something (1 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.749 s, estimated 2 s
Ran all test suites.

and failing with the following, more minimalist test:

import { PrismaClient } from "@prisma/client";

describe("schema", () => {
  afterAll(async () => {
    const prismaClient = new PrismaClient();
  });

  test("empty test", async () => {
  });
});

with

> jest --detectLeaks

ts-jest[config] (WARN) message TS151001: If you have issues related to imports, you should consider setting `esModuleInterop` to `true` in your TypeScript configuration file (usually `tsconfig.json`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information.
 FAIL  tests/memory.test.ts
  ● Test suite failed to run

    EXPERIMENTAL FEATURE!
    Your test suite is leaking memory. Please ensure all references are cleaned.

    There is a number of things that can leak memory:
      - Async operations that have not finished (e.g. fs.readFile).
      - Timers not properly mocked (e.g. setInterval, setTimeout).
      - Keeping references to the global scope.

      at onResult (node_modules/.pnpm/@jest+core@29.7.0/node_modules/@jest/core/build/TestScheduler.js:150:18)
      at node_modules/.pnpm/@jest+core@29.7.0/node_modules/@jest/core/build/TestScheduler.js:254:19
      at node_modules/.pnpm/emittery@0.13.1/node_modules/emittery/index.js:363:13
          at Array.map (<anonymous>)
      at Emittery.emit (node_modules/.pnpm/emittery@0.13.1/node_modules/emittery/index.js:361:23)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        1.665 s
Ran all test suites.
 ELIFECYCLE  Test failed. See above for more details.

@Jolg42 Jolg42 added bug/2-confirmed Bug has been reproduced and confirmed. and removed bug/1-unconfirmed Bug should have enough information for reproduction, but confirmation has not happened yet. labels Nov 2, 2023
@Druue
Copy link
Contributor

Druue commented Jan 3, 2024

Hey @ogroppo
I cloned your repo:

$ pnpm i

dependencies:
+ @prisma/client 3.14.0
+ prisma 3.14.0

devDependencies:
+ @types/jest 27.5.1
+ jest 28.1.0
+ ts-jest 28.0.3
+ typescript 4.7.2
+ weak-napi 2.0.2

Test on Node v16.19.1, pnpm v8.6.12

import prismaClient from "../prisma/prismaClient";

describe("schema", () => {
  afterAll(async () => {
    await prismaClient.$disconnect();
  });

  test("Deleting parent row in 1-to-n trows error", async () => {
    const user = await prismaClient.user.findFirst();
    expect(user).toBeFalsy();
  });
});

Yields

❯ pnpm t              
> jest --detectLeaks

ts-jest[config] (WARN) message TS151001: If you have issues related to imports, you should consider setting `esModuleInterop` to `true` in your TypeScript configuration file (usually `tsconfig.json`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information.
 FAIL  tests/memory.test.ts
  ● Test suite failed to run

    EXPERIMENTAL FEATURE!
    Your test suite is leaking memory. Please ensure all references are cleaned.

    There is a number of things that can leak memory:
      - Async operations that have not finished (e.g. fs.readFile).
      - Timers not properly mocked (e.g. setInterval, setTimeout).
      - Keeping references to the global scope.

      at onResult (node_modules/.pnpm/@jest+core@28.1.0/node_modules/@jest/core/build/TestScheduler.js:188:18)
      at node_modules/.pnpm/@jest+core@28.1.0/node_modules/@jest/core/build/TestScheduler.js:300:17
      at node_modules/.pnpm/emittery@0.10.2/node_modules/emittery/index.js:311:13
          at Array.map (<anonymous>)
      at Emittery.emit (node_modules/.pnpm/emittery@0.10.2/node_modules/emittery/index.js:309:23)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        1.128 s
Ran all test suites.
zsh: segmentation fault  pnpm t

The following causes the test to pass.

import prismaClient from "../prisma/prismaClient";

describe("schema", () => {
  test("Deleting parent row in 1-to-n trows error", async () => {});
});
❯ pnpm t              
> jest --detectLeaks

ts-jest[config] (WARN) message TS151001: If you have issues related to imports, you should consider setting `esModuleInterop` to `true` in your TypeScript configuration file (usually `tsconfig.json`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information.
 PASS  tests/memory.test.ts
  schema
    ✓ Deleting parent row in 1-to-n trows error (1 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.761 s, estimated 1 s
Ran all test suites.

I tried downgrading to pnpm v7.0.0 & node v16.13.2 which made no difference


On node v20.10.0 with the following test as @Jolg42 used

import { PrismaClient } from "@prisma/client";

describe("schema", () => {
  afterAll(async () => {
    const prismaClient = new PrismaClient();
  });

  test("empty test", async () => {});
});

I run into the following error:

❯ pnpm t              
> jest --detectLeaks

ts-jest[config] (WARN) message TS151001: If you have issues related to imports, you should consider setting `esModuleInterop` to `true` in your TypeScript configuration file (usually `tsconfig.json`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information.
 FAIL  tests/memory.test.ts
  ● Test suite failed to run

    EXPERIMENTAL FEATURE!
    Your test suite is leaking memory. Please ensure all references are cleaned.

    There is a number of things that can leak memory:
      - Async operations that have not finished (e.g. fs.readFile).
      - Timers not properly mocked (e.g. setInterval, setTimeout).
      - Keeping references to the global scope.

      at onResult (node_modules/.pnpm/@jest+core@28.1.0/node_modules/@jest/core/build/TestScheduler.js:188:18)
      at node_modules/.pnpm/@jest+core@28.1.0/node_modules/@jest/core/build/TestScheduler.js:300:17
      at node_modules/.pnpm/emittery@0.10.2/node_modules/emittery/index.js:311:13
          at Array.map (<anonymous>)
      at Emittery.emit (node_modules/.pnpm/emittery@0.10.2/node_modules/emittery/index.js:309:23)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        0.36 s
Ran all test suites.
zsh: segmentation fault  pnpm t

Commenting out the client yields a passing test.

import { PrismaClient } from "@prisma/client";

describe("schema", () => {
  afterAll(async () => {
    // const prismaClient = new PrismaClient();
  });

  test("empty test", async () => {});
});

Updating to Prisma v5.7.1 didn't affect output here:

import { PrismaClient } from "@prisma/client";

describe("schema", () => {
  afterAll(async () => {
    const prismaClient = new PrismaClient();
  });

  test("empty test", async () => {});
});

Yielded:

❯ pnpm t

> prisma-destroy-bug@1.0.0 test /Users/soph/src/repros/prisma-memory-leak-repro
> jest --detectLeaks

ts-jest[config] (WARN) message TS151001: If you have issues related to imports, you should consider setting `esModuleInterop` to `true` in your TypeScript configuration file (usually `tsconfig.json`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information.
 FAIL  tests/memory.test.ts
  ● Test suite failed to run

    EXPERIMENTAL FEATURE!
    Your test suite is leaking memory. Please ensure all references are cleaned.

    There is a number of things that can leak memory:
      - Async operations that have not finished (e.g. fs.readFile).
      - Timers not properly mocked (e.g. setInterval, setTimeout).
      - Keeping references to the global scope.

      at onResult (node_modules/.pnpm/@jest+core@28.1.0/node_modules/@jest/core/build/TestScheduler.js:188:18)
      at node_modules/.pnpm/@jest+core@28.1.0/node_modules/@jest/core/build/TestScheduler.js:300:17
      at node_modules/.pnpm/emittery@0.10.2/node_modules/emittery/index.js:311:13
          at Array.map (<anonymous>)
      at Emittery.emit (node_modules/.pnpm/emittery@0.10.2/node_modules/emittery/index.js:309:23)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        0.493 s, estimated 1 s
Ran all test suites.
zsh: segmentation fault  pnpm t

While the following passed

import { PrismaClient } from "@prisma/client";

describe("schema", () => {
  afterAll(async () => {
    // const prismaClient = new PrismaClient();
  });

  test("empty test", async () => {});
});

Some quick graphing I did

describe("schema", () => {
  memoryLogger.log();

  afterAll(async () => {
    await prismaClient.$disconnect();
  });

  for (let i = 0; i < 100000; i++) {
    memoryLogger.log();
    test("test", async () => {
      const user = await prismaClient.user.findFirst();
      expect(user).toBeFalsy();
    });

    memoryLogger.log();
  }
});

Node v20.10.0
image

vs

describe("schema", () => {
  memoryLogger.log();

  afterAll(async () => {});

  for (let i = 0; i < 100000; i++) {
    memoryLogger.log();
    test("test", async () => {
      const user = null;
      expect(user).toBeFalsy();
    });

    memoryLogger.log();
  }
});
image

@Jolg42 Jolg42 added bug/0-unknown Bug is new, does not have information for reproduction or reproduction could not be confirmed. and removed bug/2-confirmed Bug has been reproduced and confirmed. labels Jan 4, 2024
@Jolg42
Copy link
Member

Jolg42 commented Jan 4, 2024

@ogroppo It's been a while since you opened this issue. As you can see, we investigated and posted results, but we didn't find an actual memory leak.

Jest --detectLeaks is an experimental feature, which is undocumented, and from our experience it's too often unreliable. You can see that similar results can be obtained without using Prisma.

If you have a reproduction where a memory leak can be observed, we will be happy to attempt a reproduction and investigate again.

I hope I can create a code template in the future with some guidelines to help with potential memory leaks issue in the future (to be done)

@Jolg42 Jolg42 closed this as not planned Won't fix, can't repro, duplicate, stale Jan 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug/0-unknown Bug is new, does not have information for reproduction or reproduction could not be confirmed. kind/bug A reported bug. team/client Issue for team Client. topic: jest topic: memory leak topic: performance/memory
Projects
None yet
Development

No branches or pull requests

6 participants