vercel / vercel/next.js

No way to subscribe to files unmounting in development

Open
#46,018 6 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug not stale
Dominant language
JavaScript
Stars
142k
Forks
32.5k
Avg merge
2d 14h
Merged PRs (30d)
351

Description

Verify canary release
  • I verified that the issue exists in the latest Next.js canary release
Provide environment information
Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 21.6.0: Mon Aug 22 20:20:05 PDT 2022; root:xnu-8020.140.49~2/RELEASE_ARM64_T8101
Binaries:
  Node: 16.15.0
  npm: 8.5.5
  Yarn: N/A
  pnpm: 7.25.1
Relevant packages:
  next: 12.3.0
  eslint-config-next: N/A
  react: 18.1.0
  react-dom: 18.1.0
Which area(s) of Next.js are affected? (leave empty if unsure)

No response

Link to the code that reproduces this issue

https://stackblitz.com/edit/vercel-next-js-jqfycd?file=server%2FBackendMock.ts

To Reproduce
  1. Create a singleton file which tracks its own initialization, then logs every 10s:
class Test {
    static hasInitialized = false;
    static init() {
        if (!this.hasInitialized) {
            this.hasInitialized = true;
            setInterval(() => console.log("Polling something"), 10000);
        }
    }
}
  1. call this function from a getServersideProps() or API endpoint
  2. Make a change to the API or one of its dependencies
Describe the Bug

Related to https://github.com/vercel/next.js/issues/45204, unchanged files will be reloaded by nextjs if a different dependency of an API route (e.g.) is changed. While this alone seems to be a bug, the lack of a solution for "shutting down" files that get reloaded also seems to be an issue.

In particular, database connections or singleton handler classes, or anything polling, will not shut down when files are reloaded. This leads to redundant work being done, excessive memory consumption (eventually leading to OOMs), and pain in debugging things (multiple instances of singletons all living around at the same time).

One workaround is storing the instance in a global variable, and either shutting down any existing one if detected or just reusing the existing one. However, this is rather hacky and relies on abusing the global variable space to dump every singleton. Additionally the need to shutdown and restart database connections in these situations is rather painful, so I opt to reuse existing connections, but that prevents reloads of changes to initialization logic (would be nice if I could detect a reload due to change vs. reload due to other file changing)

Expected Behavior

There should be a way (similar to hot module reloading's module.hot.*) to "subscribe" to a module being unloaded. When this happens, it could clear any intervals, and close any connections.

Which browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the linked StackBlitz reproduction, especially server/BackendMock.ts, and compare its reload behavior with the related issue #45204. Define how a development-server module-unload subscription should work, then verify that intervals, database connections, and singleton handlers can be cleaned up when dependencies reload.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, nextjs, node.js
Domain
backend, devtools
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.