-
-
Notifications
You must be signed in to change notification settings - Fork 2
Add worker/clustering support for Bun runtime #9
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -73,7 +73,13 @@ export const _jet_middleware: Record< | |||||||||||||||||||||
| export const server = ( | ||||||||||||||||||||||
| plugs: JetPlugin[], | ||||||||||||||||||||||
| options: jetOptions, | ||||||||||||||||||||||
| ): { listen: any; edge: boolean } => { | ||||||||||||||||||||||
| ): { | ||||||||||||||||||||||
| listen: any; | ||||||||||||||||||||||
| edge: boolean; | ||||||||||||||||||||||
| isPrimary?: boolean; | ||||||||||||||||||||||
| stop?: () => void; | ||||||||||||||||||||||
| close?: (cb?: () => void) => void; | ||||||||||||||||||||||
| } => { | ||||||||||||||||||||||
| let server; | ||||||||||||||||||||||
| let server_else; | ||||||||||||||||||||||
| const runtimeConfig = options.runtimes; | ||||||||||||||||||||||
|
|
@@ -144,6 +150,40 @@ export const server = ( | |||||||||||||||||||||
| }; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| if (runtime["bun"]) { | ||||||||||||||||||||||
| const clusterConfig = runtimeConfig?.bun?.cluster; | ||||||||||||||||||||||
| if (clusterConfig) { | ||||||||||||||||||||||
| const cluster = require("node:cluster"); | ||||||||||||||||||||||
| const os = require("node:os"); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (cluster.isPrimary) { | ||||||||||||||||||||||
| const numWorkers = typeof clusterConfig === "number" | ||||||||||||||||||||||
| ? clusterConfig | ||||||||||||||||||||||
| : os.cpus().length; | ||||||||||||||||||||||
|
Comment on lines
+159
to
+161
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Validate that worker count is a positive integer. If a user passes 🛡️ Suggested validation if (cluster.isPrimary) {
- const numWorkers = typeof clusterConfig === "number"
- ? clusterConfig
- : os.cpus().length;
+ const numWorkers = typeof clusterConfig === "number"
+ ? Math.max(1, Math.floor(clusterConfig))
+ : os.cpus().length;📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| server = { | ||||||||||||||||||||||
| listen(port: number) { | ||||||||||||||||||||||
| LOG.log(`Primary ${process.pid} is starting ${numWorkers} workers`, "info"); | ||||||||||||||||||||||
| for (let i = 0; i < numWorkers; i++) { | ||||||||||||||||||||||
| cluster.fork(); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| cluster.on("exit", (worker: any) => { | ||||||||||||||||||||||
| LOG.log(`worker ${worker.process.pid} died, restarting...`, "warn"); | ||||||||||||||||||||||
| cluster.fork(); | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
| stop() { | ||||||||||||||||||||||
| for (const id in cluster.workers) { | ||||||||||||||||||||||
| cluster.workers[id].kill(); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| }, | ||||||||||||||||||||||
|
Comment on lines
+175
to
+179
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add null check before calling Workers can exit between iteration start and the 🛡️ Suggested fix stop() {
for (const id in cluster.workers) {
- cluster.workers[id].kill();
+ cluster.workers[id]?.kill();
}
},📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
| edge: false, | ||||||||||||||||||||||
| isPrimary: true, | ||||||||||||||||||||||
| }; | ||||||||||||||||||||||
| return server; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (options.upgrade && options.upgrade === true) { | ||||||||||||||||||||||
| server = { | ||||||||||||||||||||||
| listen(port: number) { | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
Does Bun support node:cluster module for worker processes?💡 Result:
Yes, Bun supports the node:cluster module for worker processes. It was implemented in Bun v1.1.25 (August 2024) via PR
#11492and is documented in the official Bun API reference. However, it has limitations: handles and file descriptors cannot be passed between workers (limiting TCP server load-balancing to Linux via SO_REUSEPORT), and it is described as "implemented but not battle-tested."Citations:
node:clusteroven-sh/bun#11492node:clustermodule oven-sh/bun#2428Verify Bun's
node:clustersupport meets production requirements.Bun supports
node:cluster(as of v1.1.25), but with important limitations: handles and file descriptors cannot be passed between workers, and TCP server load-balancing on Bun is limited to Linux usingSO_REUSEPORT. Additionally, the feature is documented as "implemented but not battle-tested." Ensure the implementation accounts for these constraints and is tested on the target platform before production deployment.🤖 Prompt for AI Agents