oven-sh / bun

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

Implement `node:cluster` module #2428

Closed Tushar-Chavan14 closed 2 months ago

Tushar-Chavan14 commented 1 year ago

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

Jarred-Sumner commented 1 year ago

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

ThatOneCalculator commented 1 year ago

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.

xb1itz commented 1 year ago

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

CharnSrinivas commented 1 year ago

+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

melroy89 commented 1 year ago

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.

joshholly commented 1 year ago

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

ThatOneCalculator commented 1 year ago

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

ElYaiko commented 1 year ago

+1

masfahru commented 1 year ago

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

calebeaires commented 1 year ago

@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 },
    });
}
masfahru commented 1 year ago

@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

calebeaires commented 1 year ago

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

ThatOneCalculator commented 1 year ago

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

calebeaires commented 1 year ago

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.

ednt commented 11 months ago

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

THIS!

CsVeryLoveXieWenLi commented 11 months ago

没有像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.

Matthew-Tersigni commented 11 months ago

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

arbile26 commented 11 months ago

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

ThatOneCalculator commented 11 months ago

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

ndaidong commented 11 months ago

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

ganeshkbhat commented 11 months ago

+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 },
    });
}
rgillan commented 8 months ago

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.

chlorophant commented 7 months ago

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

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

isaadabbasi commented 7 months ago

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.

antn9x commented 7 months ago

I hope this feature release soon.

waghanza commented 7 months ago

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

rgillan commented 7 months ago

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

AlexanderEpolite commented 7 months ago

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.

rgillan commented 7 months ago

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

Ivanmatthew commented 7 months ago

+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?).

snorremd commented 7 months ago

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.

Just for any other MacOS user like me coming to this thread to find out why reusePort is not working. It seems this feature works different on older FreeBSD and Darwin than Linux according to this StackOverflow thread. On MacOS the SO_REUSEPORT implementation does not round robin the TCP requests. Instead it sends the requests to the last process to attach to the socket.

Not sure if Darwin will ever implement this or not. So for the time being MacOS users will need to put a proxy in front of their Bun servers to support multiple process request handling.

Bytedefined commented 6 months ago

Would be great to see support sometime soon!

elliotthill commented 5 months ago

For a lot of us running regular servers, like ec2 instances, we cannot run Bun in production due to this.

Yes its possible to rewrite your app to use bun.serve() or rearchitect it to run on single threaded containers, but thats not really a drop in replacement as is claimed.

Given its the 12th most thumbs up'd issue out of ~2k, can it be added to the roadmap?

mrtcmn commented 5 months ago

This is power of the nodejs. I'll waiting node:cluster implemetation for migrate my all servers to bun.

lodembeep commented 5 months ago

What if you need clustering for tasks other than serving http requests ?

Clustering is important for non web tasks, i usually spawn workers on server side for CPU intensive tasks, nothing related to serving at all.

Jarred-Sumner commented 5 months ago

We are planning to implement node:cluster towards the end of this month.

lodembeep commented 5 months ago

We are planning to implement node:cluster towards the end of this month.

Awesome !!! I will spread the word :)

haimev commented 5 months ago

cool! great news

liudonghua123 commented 5 months ago

I tried the latest bun 1.1.9. And it seemed not support currently. Hope next release could support it.

 > bun server.js
Primary 11780 is running
14 |   warned.add(feature), console.warn(new NotImplementedError(feature, issue));
15 | }, $;
16 |
17 | class NotImplementedError extends Error {
18 |   code;
19 |   constructor(feature, issue) {
                               ^
NotImplementedError: node:cluster is not yet implemented in Bun. Track the status & thumbs up the issue: https://github.com/oven-sh/bun/issues/2428
 code: "ERR_NOT_IMPLEMENTED"

      at new NotImplementedError (internal:shared:19:27)
      at internal:shared:2:69
      at fork (node:cluster:25:13)
      at D:\code\node\playground\cluster\server.js:13:5

Bun v1.1.9 (Windows x64)

 >
i8ramin commented 5 months ago

Hello has anyone successfully been able to use pm2 with bun compiled node binary? i've tried many different commands and variations but cannot figure it out. any help would be greatly appreciated.

techsin commented 4 months ago

is it out?

dienstbereit commented 4 months ago

Hello has anyone successfully been able to use pm2 with bun compiled node binary? i've tried many different commands and variations but cannot figure it out. any help would be greatly appreciated.

I assume that as soon as node:cluster is implemented, bun will also run with pm2 in cluster mode out-of-the-box. At least I hope so ;-)

ajimix commented 4 months ago

We are planning to implement node:cluster towards the end of this month.

+1 if you are here in June or later, waiting for it to be implemented 😄

Jarred-Sumner commented 4 months ago

@nektro is working on this, please follow along in #11492

lortmorris commented 2 months ago

I need using clusters for s42-core. When you think guys this features will be available?

Jarred-Sumner commented 2 months ago

Initial support for the cluster module will be part of the Bun v1.1.25 release, thanks to @nektro!

dienstbereit commented 2 months ago

Magnificent… thanks to @nektro 👏 Now I can finally go into production with my project 🤩

censujiang commented 2 months ago

Thank you bro!

kravetsone commented 2 months ago

It's happening! Thanks!

It would be nice if you provide somewhere in Documentation prons and cons of usage node:cluster or reusePort: true

kravetsone commented 2 months ago

It's happening! Thanks!

It would be nice if you provide somewhere in Documentation prons and cons of usage node:cluster or reusePort: true

I guess also provide benchmarks of normal mode, cluster, reusePort will be great)