oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
73.6k stars 2.72k forks source link

Nuxt v3.11.x with Bun Monorepo segfaults #11490

Closed Eckhardt-D closed 4 months ago

Eckhardt-D commented 4 months ago

How can we reproduce the crash?

I wish I could share the exact source as I think this is a pretty specific setup:

bun workspace with:

["packages/*", "apps/*"]

A Nuxt Layer with nuxt/ui and nuxt/auth-utils installed in packages/core:

cwd: packages/core

bunx nuxt module add ui && bunx nuxt module add auth-utils

cwd: apps/webapp:

// nuxt.config.ts
export default defineNuxtConfig({
  extends: ['core-app'] // workspace dep to packages/core
})

Updated dev script in apps/webapp/package.json:

"dev": "bunx --bun nuxt dev"

Create a basic server handler in apps/webapp/server/api/index.get.ts

// defineEventHandler is auto-imported (maybe a cause?)
export default defineEventHandler(() => []);

Start the dev server:

cwd: apps/webapp

bun dev

Works fine. Now update the apps/webapp/server/api/index.get.ts file and save. HMR attempts and then this crash happens.

JavaScript/TypeScript code that reproduces the crash?

Happens with HMR when the following conditions are met:

- The setup as above.
- The /api page has to be requested / reloaded at least once in the browser.
- The `apps/webapp/server/api/index.get.ts` file must be saved

Seems to be an issue probably with Vite / WebSocket.

Relevant log output

ℹ Tailwind Viewer: http://localhost:3000/_tailwind/                nuxt:tailwindcss 7:18:14 AM
ℹ Vite client warmed up in 2689ms                                                   7:18:17 AM
ℹ Vite server warmed up in 2029ms                                                   7:18:17 AM
✔ Nuxt Nitro server built in 506 ms                                           nitro 7:18:17 AM
✔ Nuxt Nitro server built in 89 ms                                            nitro 7:18:34 AM

Stack Trace (bun.report)

Bun v1.1.10 (5102a94) on macos aarch64 [RunAsNodeCommand]

Segmentation fault at address 0x00000011

Eckhardt-D commented 4 months ago

I'm able to pinpoint the issue!

There is a database connection with postgres.js and drizzle. The connection is established once and then left for the driver to manage / reuse sockets.

When I refactor to destroy and recreate the connection on each request like e.g.

export default defineEventHandler(async () => {
  const { db, connection } = createDatabase()
  const users = await listUsers(db)
  connection.end()
  return users
})

Then the crash does not occur anymore. My thoughts are that when a connection is opened and Vite does it's HMR on the Nitro server, the process of re-evaluating the imported db code causes Bun to crash on something happening in the connection. With Node the connection still persists after HMR. I'll test in an isolated env and see if I can have a minimum reproduction.

Jarred-Sumner commented 4 months ago

@Eckhardt-D this bug is mostly caused by us calling into JavaScript as a side effect of closing all the open sockets (the close handler) when a Worker is terminating

raggesilver commented 4 months ago

I have one connection for the entire project (I don't call createDatabase on each request). I tried creating a Nitro plugin that closes the connection on shutdown. The connection is closed and I see the logs in the console, but I still get a segfault.

export default defineNitroPlugin((nitro) => {
  nitro.hooks.hook("close", async () => {
    console.log("Closing the database connection...");
    await connection.end();
    console.log("Database connection closed.");
  });
});
Jarred-Sumner commented 4 months ago

Fixed via https://github.com/oven-sh/bun/pull/11635 and #11494

The fix will land in Bun v1.1.13, but you can try it in canary bun upgrade --canary. If you still run into this issue, please let us know.