Skip to content
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

EADDRINUSE: Failed to start server. Is port 3000 in use? #9560

Closed
stefanos82 opened this issue Mar 22, 2024 · 7 comments
Closed

EADDRINUSE: Failed to start server. Is port 3000 in use? #9560

stefanos82 opened this issue Mar 22, 2024 · 7 comments
Labels
bug Something isn't working

Comments

@stefanos82
Copy link

What version of Bun is running?

1.0.33+9e91e137f

What platform is your computer?

Linux debian 6.6.15-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.6.15-2 (2024-02-04) x86_64 GNU/Linux

What steps can reproduce the bug?

Code directly taken from official website works as expected

image

spawn.tsx though with

import os from 'node:os';

// @ts-ignore
const numCPUs = os.availableParallelism();

for (let i = 0; i < numCPUs; i++) {
    Bun.spawn(['bun', 'src/index.tsx'], {
        stdio: ['inherit', 'inherit', 'inherit'],
        env: { ...process.env },
    });
}

produces EADDRINUSE: Failed to start server. Is port 3000 in use?.

Is it really a bug or am I doing something wrong here?

What is the expected behavior?

To see the same output as Elysia.js that works with spawn:

image

What do you see instead?

I see this

image

Additional information

No response

@stefanos82 stefanos82 added the bug Something isn't working label Mar 22, 2024
@ScribeSavant
Copy link

Can you check the port is already taken by another process sudo lsof -i :3000 if you see the port already taken or your program just working on background you can kill it with sudo kill -9 PID

@stefanos82
Copy link
Author

Can you check the port is already taken by another process sudo lsof -i :3000 if you see the port already taken or your program just working on background you can kill it with sudo kill -9 PID

Only bun is reported:

image

The problem is, without the use of spawn, everything works as expected.

As soon as I execute the aforementioned example, it throws the message EADDRINUSE: Failed to start server. Is port 3000 in use? but if I run directly the src/index.tsx, it works just fine:

image

@ScribeSavant
Copy link

ScribeSavant commented Mar 22, 2024

You can't run multi server on same port you should use different port for each server like 3000/3001/3002

This is not a bug, this is how TCP works

@stefanos82
Copy link
Author

stefanos82 commented Mar 22, 2024

I have already tried this; still the same message about port 3000, even though I replaced it with 3300; it would still complain about port 3000 for some reason...

Where should I go to change the default port for Bun.spawn?

@ScribeSavant
Copy link

ScribeSavant commented Mar 22, 2024

Here is an example

// file: index.ts

const port = parseInt(Bun.argv.slice(2)[0].split("=")[1]);

const server = Bun.serve({
  port: port,
  fetch(request) {
    return new Response("Welcome to Bun!");
  },
});

console.log(`Listening on localhost:${server.port}`);
process.once("SIGINT", () => {
  server.stop();
});
process.once("SIGTERM", () => {
  server.stop();
});
// file: spawn.ts

import os from "node:os";

// @ts-ignore
const numCPUs = os.availableParallelism();

for (let i = 0; i < numCPUs; i++) {
  Bun.spawn(["bun", "./index.ts", `--port=300${i + 1}`], {
    stdio: ["inherit", "inherit", "inherit"],
    env: { ...process.env },
  });
}

output

image

Do not use --watch otherwise you will get error after changes

@stefanos82
Copy link
Author

stefanos82 commented Mar 22, 2024

These are your sub-processes; which one is your main / parent process that gets spawned? It should be the one that starts with port 3000; there's no reason to benchmark each sub-process separately, it cannot be done this way.

See how Elysia accomplishes the working output and compare it with your custom implementation, unless I'm missing something here which confuses me even further...

Here's node.js's example with Cluster:

import cluster from 'node:cluster';
import http from 'node:http';
import { availableParallelism } from 'node:os';
import process from 'node:process';

const numCPUs = availableParallelism();

if (cluster.isPrimary) {
  console.log(`Primary ${process.pid} is running`);

  // Fork workers.
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on('exit', (worker, code, signal) => {
    console.log(`worker ${worker.process.pid} died`);
  });
} else {
  // Workers can share any TCP connection
  // In this case it is an HTTP server
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end('hello world\n');
  }).listen(3000); // Original example is `.listen(8000);`, I replaced it with port 3000

  console.log(`Worker ${process.pid} started`);
}

The execution:

image

The actual wrk benchmark:

image

@stefanos82
Copy link
Author

Thanks to FrameworkBenchmarks I have found the cause of my problem: I should have added reusePort: true right after port: 3000 [1].

[1] https://github.com/TechEmpower/FrameworkBenchmarks/blob/master/frameworks/TypeScript/bun/src/index.ts#L4-L7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants