bun icon indicating copy to clipboard operation
bun copied to clipboard

Implement `node:cluster` module

Open Tushar-Chavan14 opened this issue 2 years ago • 39 comments

What version of Bun is running?

0.5.7

What platform is your computer?

Linux 6.2.0-76060200-generic x86_64 x86_64

What steps can reproduce the bug?

bun i rate-limiter-flexible

import { RateLimiterMemory } from "rate-limiter-flexible";

const rateLimiter = new RateLimiterMemory({ points: 5, duration: 120, });

What is the expected behavior?

No response

What do you see instead?

No response

Additional information

No response

Tushar-Chavan14 avatar Mar 19 '23 12:03 Tushar-Chavan14

We haven't implemented the Node.js cluster module yet.

Jarred-Sumner avatar Mar 20 '23 11:03 Jarred-Sumner

Is there currently any other way to do multiprocessing/multithreading with bun? This seems like it should be a very high priority item to support.

ThatOneCalculator avatar Sep 08 '23 16:09 ThatOneCalculator

+1 on this. The lack of node:cluster implementation is probably the main reason we are not switching to Bun right now.

xb1itz avatar Sep 10 '23 07:09 xb1itz

+1 on this. The lack of node:cluster implementation is probably the main reason we are not switching to Bun right now. Same here i am shifting back to node since i get know that node:cluster is not available yet

CharnSrinivas avatar Sep 12 '23 14:09 CharnSrinivas

I got indeed:

error: Could not resolve Node.js builtin: "cluster". To use Node.js builtins, set target to 'node' or 'bun'

const cluster = require('cluster')

I was very surprised to see this error. EDIT: I know cluster is not yet implemented. But then don't call it bun 1.0 yet.

melroy89 avatar Sep 16 '23 17:09 melroy89

I ran bun --bun run dev to run my nextJS app. And I got this exact error.

joshholly avatar Sep 18 '23 08:09 joshholly

Well, node:cluster isn't implemented yet, so that's why you're seeing the error.

ThatOneCalculator avatar Sep 18 '23 14:09 ThatOneCalculator

+1

ElYaiko avatar Sep 25 '23 13:09 ElYaiko

For now (Bun v.1.0.3), I can imitate the behavior of the node:cluster in Bun to spawn as many server instances as the number of CPU cores, using this script.

spawn.ts

import os from "node:os";

const numCPUs = os.cpus().length;
for (let i = 0; i < numCPUs; i++) {
  Bun.spawn(["bun", "index.ts"], {
    stdio: ["inherit", "inherit", "inherit"],
    env: { ...process.env },
  });
}

index.ts

Bun.serve({
  port: 8080,
  reusePort: true, // allow Bun server instances to use same port 
  fetch(req: Request) {
    // ...

run bun spawn.ts

masfahru avatar Sep 29 '23 01:09 masfahru

@masfahru,

I performed the test and observed that the process ID remains the same every time I access the endpoint and print it. It appears that the access point is not redistributing properly.

 if (process.pid) {
            console.log(process.pid);
 }

index.ts


const server = Bun.serve({
    port: 3000,
    // @ts-ignore
    reusePort: true, // allow Bun server instances to use same port
    fetch(request) {
        if (process.pid) {
            console.log(process.pid);
        }
        return new Response("Welcome to Bun!");
    },
});

console.log(`Listening on localhost:${server.port}`);

cluster.ts


import os from "node:os";

const numCPUs = os.cpus().length;
for (let i = 0; i < numCPUs; i++) {
    Bun.spawn(["bun", "index.ts"], {
        stdio: ["inherit", "inherit", "inherit"],
        env: { ...process.env },
    });
}

calebeaires avatar Oct 06 '23 12:10 calebeaires

@calebeaires

SO_REUSEPORT is a builtin way to do load balancing, but it only really works properly on Linux.

Sorry, I don't know how load balancing works in Bun. To fulfill my curiosity about Bun server performance, I have tested the script in the TechEmpower Framework Benchmark, and the result is amazing. Bun is able to serve up to 2.7M requests per second for plain text test.

image https://www.techempower.com/benchmarks/#section=test&runid=235acf72-7de8-4f61-baca-36c2df35a5c0&test=plaintext&l=zik0zj-33z

masfahru avatar Oct 06 '23 16:10 masfahru

@masfahru, you're right. I've tested in a linux machine and works like a charm.

calebeaires avatar Oct 06 '23 16:10 calebeaires

@calebeaires Would you mind sharing the details on what hardware/setup was used to achieve those numbers?

ThatOneCalculator avatar Oct 06 '23 18:10 ThatOneCalculator

On M1 Mac OS 8 cores, it does not work. On linux, Ubuntu 22, 2 cores I could get a good result. Sending concurrent requests to Bun server that console log the process.id numbers, we get different results.

calebeaires avatar Oct 06 '23 18:10 calebeaires

+1 on this. The lack of node:cluster implementation is probably the main reason we are not switching to Bun right now.

THIS!

ednt avatar Nov 01 '23 09:11 ednt

没有像Nodejs那样的多进程/线程,我觉得这应该是一个优先级很高的问题,并且应该写到示例文档里,我认为应该如此,毕竟这是一个性能相关的问题。我看了一下回复列举的代码,等会试试看有没有效果。

Google Machine Translate -> There are no multi-processes/threads like Nodejs. I think this should be a high priority issue and should be written into the sample documentation. I think it should be so. After all, this is a performance related issue. I took a look at the code listed in the reply and will try it later to see if it has any effect.

CsVeryLoveXieWenLi avatar Nov 01 '23 16:11 CsVeryLoveXieWenLi

+1 I Can't fully convert my node apps to bun without this feature.

Matthew-Tersigni avatar Nov 01 '23 18:11 Matthew-Tersigni

I do wait for this feature in order to switch to bun on all my node apps.

arbile26 avatar Nov 06 '23 21:11 arbile26

Can we please keep this thread productive, such as discussing potential implementations?

ThatOneCalculator avatar Nov 06 '23 23:11 ThatOneCalculator

I'm looking forward to seeing this feature implemented in Bun.

ndaidong avatar Nov 10 '23 08:11 ndaidong

+1 for this.

I am also recommend implementing cluster_thread module which is genuinely a good starting point for creating clusters of threads like clusters of processes in node.js. Currently a multi-threading option is a little buggy. There is no random round robin as well in Windows due to absence of file descriptor module [presumed - check] in windows environment.

This is the Node.js Suggestion recommendation. https://github.com/nodejs/node/issues/48350

@masfahru,

I performed the test and observed that the process ID remains the same every time I access the endpoint and print it. It appears that the access point is not redistributing properly.

 if (process.pid) {
            console.log(process.pid);
 }

index.ts

const server = Bun.serve({
    port: 3000,
    // @ts-ignore
    reusePort: true, // allow Bun server instances to use same port
    fetch(request) {
        if (process.pid) {
            console.log(process.pid);
        }
        return new Response("Welcome to Bun!");
    },
});

console.log(`Listening on localhost:${server.port}`);

cluster.ts

import os from "node:os";

const numCPUs = os.cpus().length;
for (let i = 0; i < numCPUs; i++) {
    Bun.spawn(["bun", "index.ts"], {
        stdio: ["inherit", "inherit", "inherit"],
        env: { ...process.env },
    });
}

ganeshkbhat avatar Nov 28 '23 03:11 ganeshkbhat

Actually the feature for Bun.serve to allow port reuse (reusePort:true) and simple Bun.spawn of a number of processes works a treat. We have refactored a node:cluster websocket application using this simple approach and found it to be quite straightforward (on Linux at least), sharing both 443 and 80 (hsts). The ipc comms makes it a pretty simple drop in replacement with some simple rewrites. Subsequent websocket connections are load balanced by the OS in round robin. Still need to load test but functional.

rgillan avatar Feb 14 '24 08:02 rgillan

We haven't implemented the Node.js cluster module yet.

Is there a timeline on this? Would love to have this feature!

chlorophant avatar Mar 04 '24 01:03 chlorophant

Just came to this thread to tell, all the benchmark blogs n videos are comparing nodejs (clustered), Go (which is natively clustered) vs Bun. Though Bun outperform node on single process mode but its really not good for general sentiment build up. It'd be really hard to educate the masses on fair grounds of comparison. If we could implement clustered mode that would be really great.

isaadabbasi avatar Mar 04 '24 16:03 isaadabbasi

I hope this feature release soon.

antn9x avatar Mar 07 '24 02:03 antn9x

Just came to this thread to tell, all the benchmark blogs n videos are comparing nodejs (clustered), Go (which is natively clustered) vs Bun.

Not really https://web-frameworks-benchmark.netlify.app/result?l=javascript is comparing node vs bun on with clustering for both of them. Clustering could be done, but it depends ... It could be useless, with some architecture, to have clustering mode

waghanza avatar Mar 07 '24 08:03 waghanza

So in my opinion having used node:cluster for many years (and the cluster module pre integration), the ability to reuse sockets in the Bun.serve implementation pretty much removes the need for node:cluster support in Bun for some of the use cases. The IPC channel support is identical syntax, and things like http/s and websocket server port sharing just work out of the box on Linux. Spawn separate workers and reuse the ports. Reach out if you need any guidance but we've pretty much deprecated the need for the cluster capability with what Bun already has implemented. Cheers Rob

rgillan avatar Mar 07 '24 09:03 rgillan

So in my opinion having used node:cluster for many years (and the cluster module pre integration), the ability to reuse sockets in the Bun.serve implementation pretty much removes the need for node:cluster support in Bun for most of the use cases. The IPC channel support is identical syntax, and things like http/s and websocket server port sharing just work out of the box on Linux. Spawn separate workers and reuse the ports. Reach out if you need any guidance but we've pretty much deprecated the need for the cluster capability with what Bun already has implemented. Cheers Rob

What if I want to have multiple instances of smtp-server running on port 25? Only other option would be nginx, but that comes with its own set of issues.

AlexanderEpolite avatar Mar 07 '24 10:03 AlexanderEpolite

So in my opinion having used node:cluster for many years (and the cluster module pre integration), the ability to reuse sockets in the Bun.serve implementation pretty much removes the need for node:cluster support in Bun for most of the use cases. The IPC channel support is identical syntax, and things like http/s and websocket server port sharing just work out of the box on Linux. Spawn separate workers and reuse the ports. Reach out if you need any guidance but we've pretty much deprecated the need for the cluster capability with what Bun already has implemented. Cheers Rob

What if I want to have multiple instances of smtp-server running on port 25? Only other option would be nginx, but that comes with its own set of issues.

Understood, and yes you'd need to handle that externally (nginx, possibly pm2 would be another option but not sure) Another approach we have done in the nodejs world is have a single process handle the raw port, then workers doing what's needed. I've modified my comment to say some rather than most

rgillan avatar Mar 08 '24 03:03 rgillan

+1 on this. The lack of node:cluster implementation is probably the main reason we are not switching to Bun right now.

+1

So in my opinion having used node:cluster for many years (and the cluster module pre integration), the ability to reuse sockets in the Bun.serve implementation pretty much removes the need for node:cluster support in Bun for some of the use cases. The IPC channel support is identical syntax, and things like http/s and websocket server port sharing just work out of the box on Linux. Spawn separate workers and reuse the ports. Reach out if you need any guidance but we've pretty much deprecated the need for the cluster capability with what Bun already has implemented. Cheers Rob

The use-case would still be to reinforce Bun's statement of being a "drop-in" replacement for Node, since most of the functionality that entails the cluster module is apparently already implemented, I hope some of the code can be reused for a node:cluster module (mock?).

Ivanmatthew avatar Mar 25 '24 21:03 Ivanmatthew